Thursday, April 14, 2016

Issue with JQuery ajax request which uses CORS when JSONP is explicitly specified in request options

Sometime ago we faced with interesting issue: we use JSONP request via jQuery.ajax() to send data to another domain:

   1: jQuery.ajax({
   2:     url: url,
   3:     data: { ... },
   4:     dataType: "jsonp",
   5:     success: function(msg) {
   6:         ...
   7:     }
   8: });

On most sites it works as expected, i.e. it sends HTTP GET request and passes JSONP callback function name in query string parameter. But on one site because of some reason it sends HTTP OPTION verb to the same url, which as you probably know, happens when using CORS. Since our endpoint didn’t support CORS we got errors:

Chrome:

XMLHttpRequest cannot load http://example1.com. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://example2.com is therefore not allowed access. The response had HTTP status code 404.

FF:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://example1.com. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

IE:

XMLHttpRequest: Network Error 0x80070005, Access is denied.

In order to fix the issue, i.e. in order to force jQuery to use JSONP instead of CORS additional parameter “crossDomain: true” should be added to request options:

   1: jQuery.ajax({
   2:     url: url,
   3:     data: { ... },
   4:     dataType: "jsonp",
   5:     crossDomain: true,
   6:     success: function(msg) {
   7:         ...
   8:     }
   9: });

After that jQuery will start to use JSONP. However the question why it implicitly uses CORS on some sites even if we pass dataType: “jsonp” in request options is still open. If you will find the reason please share it in comments.

No comments:

Post a Comment