28

According to jQuery :

crossDomain (default: false for same-domain requests, true for cross-domain requests) Type: Boolean If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)

I don't understand the above.

If the code is

$(document).ready(function ()
{
    $.ajax(
    {
        url: 'http://es3.com/Handlers/MyHandler.ashx',
        cache: false,
        dataType: "jsonp",
        ...
        ...
    });
});

function aaa(json)
{
    alert(json.result);
}

And im specifiying datatype:jsonp, then the response is going to be application/javascript mime typed , becuase it's a script which will run in my browser.

I dont see any reason why it would not act like that when I'm running this code under the same domain. ( hence - I don't see the usages for this property).

I have made a sample

I have 2 (host tweaked) domains. es2.com and es3.com.

(notice , the url in the code is always to es3.com)

Test #1 :

Run the code from es3.com : (left pane)
Run the code from es2.com : (right pane)
crossDomain:false (default when missing).

look at the differences : (https://i.stack.imgur.com/RKyZp.jpg)

enter image description here

Test #2 :

Run the code from es3.com : (left pane)
Run the code from es2.com : (right pane)
crossDomain:true <--- notice

(https://i.stack.imgur.com/xEcyd.jpg) enter image description here

I don't see any difference.

Question :

Why / When do I need to set the crossDomain property ?

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

6 Answers6

18

The default for crossDomain is as follows:

false for same-domain requests, true for crossDomain requests

The data-type is interpreted differently depending on the value for the crossDomain setting:

"json": Evaluates the response as JSON and returns a JavaScript object. Cross-domain "json" requests are converted to "jsonp" unless the request includes jsonp: false in its request options

Because you are using jsonp instead of json you won't see any difference in your tests.

When do I need to set the crossDomain property ?

If you are making a same domain json request, and your site may redirect the request to another domain to serve the response (via HTTP 3XX), then you should set the crossDomain property to true so the response can be read by your calling script.

This gives you the advantage of retrieving JSON when making same origin requests, and the functionality of JSONP when making cross-origin requests. If CORS is active on the domain you redirect to then you can set jsonp: false in the request options.

Examples

Making a request from example.com to example.org.

  • crossDomain automatically set to true.
  • Data type set to jsonp.

Result: JSONP returned by example.org.

Making a request from example.com to example.com.

  • crossDomain automatically set to false.
  • Data type set to jsonp.

Result: JSONP returned by example.com.

Making a request from example.com to example.org.

  • crossDomain automatically set to true.
  • Data type set to json.

Result: JSONP returned by example.org.

Making a request from example.com to example.com.

  • crossDomain automatically set to false.
  • Data type set to json.

Result: JSON returned by example.com.

Making a request from example.com to example.org.

  • crossDomain automatically set to true.
  • Data type set to json.
  • jsonp is set to false.
  • example.org does not support CORS for example.com

Result: CORS error returned by browser.

Making a request from example.com to example.com, example.com redirects AJAX to example.edu.

  • crossDomain manually set to true.
  • Data type set to json.

Result: JSONP returned by example.edu.

Making a request from example.com to example.org.

  • crossDomain automatically set to true.
  • Data type set to json.
  • jsonp is set to false.
  • example.org does support CORS for example.com

Result: JSON returned by example.org.

Making a request from example.com to example.com, example.com redirects AJAX to example.edu.

  • crossDomain automatically set to false.
  • Data type set to json.
  • example.edu does not support CORS for example.com

Result: CORS error returned by browser.

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
5

Lets assume , you have have another domain spanish.es2.com which serves spanish users of your website.

You have the following requirement :

  1. Having a webpage on es2.com

  2. Call an api on es2.com and pass it some user info ( or cookie ), and get some user data. But if the user is spanish, the api on spanish.es2.com needs to be called for same data.

  3. When you do an ajax request with jQuery from es2.com to es2.com, for a spanish user :

    (a) With crossdomain disabled : Your es2.com api will find that the user is spanish, and hence do a http redirect to spanish.es2.com , which will not work due to ajax same domain policy and the ajax would fail. Redirects in ajax url -> Disallowed.

    (b) With crossdomain enabled : Your es2.com api's jsonp response,is actually loaded as a script tag wrapped in a function, hence a http redirect to other domain does not matter, and the content is still loaded, hence the ajax works. Redirects in src of a script tag -> Allowed.

Hope this makes it clear.

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
3

It isn't default false when missing. When missing it defaults to true if the domains are not the same (as in your first sample above). I think you can leave it to its default value in nearly if not all cases.

Also, when setting the cross-domain parameter, JQuery attempts to use CORS by default, not JSONP.

Here are some relevant snippets from JQuery source: https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js

variable "xhrSupported"...

xhrSupported = jQuery.ajaxSettings.xhr();

..is used to check for CORS support....

support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );

.. which is checked when making AJAX calls....

jQuery.ajaxTransport(function( options ) {
        var callback;

        // Cross domain only allowed if supported through XMLHttpRequest
        if ( support.cors || xhrSupported && !options.crossDomain ) 

Hope this helps!

morefromalan
  • 302
  • 3
  • 9
  • What do you mean by _Also, when setting the cross-domain parameter, JQuery attempts to use CORS by default,_ ? ---- CORS should be supported also by the server ( add the special header)! how come jquery tries to do CORS if it doesnt know whether the server supports CORS ? All the client knows is that he should get special tailored script to execute ( jsonp actually). – Royi Namir Jan 29 '14 at 05:30
  • Sorry - that wasn't super clear. Yes it checks for CORS support in header. What I meant was, without explicitly setting as jsonp or using something like callback=? in url -- then it will use CORS not JSONP – morefromalan Jan 30 '14 at 19:12
  • Im sorry i still don't understand your answer. Can u please supply example to this attribute usage : if exists vs not exists ... This will make me finally understand . The root of my problem is that jsonp response which is pure ajax is not subject to cross domain problem so i dont understand where is the problem. Please elaborate by different samples . Thank u verymuch – Royi Namir Jan 31 '14 at 14:50
2

As far as I can see the op is correct. Setting dataType to jsonp will create a JSONP type request; with the result written into a script block and run. Therefore forcing JSONP by setting cross-domain to true seems redundant.

However. The documentation says that "if you want to force a cross-domain request such as JSONP" thus implying that there might be other cases where you might want to force cross-domain behaviour. I'm not sure what those cases might be however.

0

If your are already specifying JSONP, then the crossDomain parameter doesn't do much. It just tells jQuery to ask for JSONP even if it's a local domain.

Let's say you are working on your machine with a local service that returns JSON or JSONP. You can use a plain $.ajax() call, which works fine. In production however, the server redirects your request to a different domain if you meet some special conditions. Prod needs to ask for JSONP, because sometimes the response comes from off-domain.

Making that $.ajax() call without crossDomain: true or datatype: 'jsonp' will assume the response can be plain JSON, so the code will fail in production.

You can also get cross-domain XML through prestidigitation like loading cross-domain XML through JSONP with YQL, which is really just wrapping it in JSONP.

Sam R
  • 696
  • 3
  • 7
  • But from the server POV it's a different implementation !!! let's say i'm asking for json result. the server knows to return only json. and so , i make an ajax request to the server which in turn directs me to domainB. now you're saying that on domainB there must be a JSONP handler to make a `callback({})` thing. is that what you're saying ? that in order for this to work , i'm as a developer must create both json responses AND(!!) jsonp responses ? – Royi Namir Feb 22 '14 at 14:26
  • It's different *both* server- and client-side, even though jQuery abstracts it away nicely. JSONP adds a script tag to the page and lets you execute a named function. You can either A) [get around CORS](http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy) to make JSON requests cross-domain, B) Specify JSONP so it's the same locally and cross-domain, or C) use JSON locally and JSONP cross-domain. Specifying `crossDomain: true` or `dataType: 'jsonp'` should have the same effect: always using JSONP. – Sam R Feb 23 '14 at 20:01
0

You're question has been very helpful for me to understand the problem that I've encountering on the use of jsonp with jQuery.
In my case, I needed to do a JSONP call to an external domain.
But the url needed to be constructed from our domain.

For example, here, i assume my website is under es2.com

JSONP call on es2.com
es2.com redirect to es3.com?newConstructedUrl=someRandomValue
es3.com?newConstructedUrl=NewCoolValue redirect to es2.com
es2.com respond setting a new cookie in the response

The code was working fine in localhost, but we had no cookie in the es2 environment.
And seeing the Debugger, the request was being done in XHR in the es2 environment
We needed then to set the crossDomain parameter to true. The JSONP request was then, done even in es2.com

Hope my use case is clear !

Mahmal Sami
  • 689
  • 7
  • 12