Dojo FAQ: How do I use CORS with Dojo?

By on January 15, 2014 1:11 pm

In web browsers that support Cross-Origin Resource Sharing (CORS) via XMLHttpRequest objects, Dojo’s XHR mechanism can make cross-domain requests out of the box.

Because of the same-origin policy of XMLHttpRequest, Dojo has long supported various methods of loading resources across domains – dojo/io/script and dojo/io/frame; dojo/request/script and dojo/request/iframe in recent versions (1.8+). However, modern web browsers have relaxed the same-origin policy to allow developers to perform cross-domain requests with one caveat: the server must allow cross-domain requests by responding to the request with the Access-Control-Allow-Origin header set to a value that includes the domain of the requesting code (or * to match all domains). If the browser supports CORS, it will complete the request as if it were a same-domain request. This feature is also available in Dojo:

require([ "dojo/request" ], function (request) {
    request("http://other.domain/resource");
});

While Dojo’s XHR mechanism supports CORS out of the box, it sets the X-Requested-With header by default, which will result in a pre-flighted request that may not be desirable. For requests that don’t include sensitive data or cause side effects, you can prevent the pre-flighted request by clearing the X-Requested-With header:

require([ "dojo/request" ], function (request) {
    request("http://other.domain/resource", {
        headers: {
            "X-Requested-With": null
        }
    });
});

If you need to send HTTP authentication credentials or cookies with your cross-domain request, simply setting the withCredentials option to true will allow the browser’s XMLHttpRequest to send that information:

require([ "dojo/request" ], function (request) {
    request("http://other.domain/resource", {
        headers: {
            "X-Requested-With": null
        },
        withCredentials: true
    });
});

Comments

  • Jim Wharton

    This fails preflight for me. OPTIONS just immediately fails. I wrote the same request in jQuery just to make sure I wasn’t crazy. It works fine there. Any other ideas for how to get this to work?

  • Did you clear the X-Requested-With header as illustrated? jQuery will not send the header if it detects a cross-domain request that could be completed without preflight without the header being set; this is not the case in Dojo. If you have, do you have a link to an example with the failure?

  • Jim Wharton

    Yep, I set X-Requested-With to null. I actually just posted a stackoverflow question with the code example: http://stackoverflow.com/questions/21373174/dojo-cant-make-a-cors-request-jquery-can

  • I’ve posted an answer on the stack overflow question.

  • anchorite

    X-Requested-With was not enough for for me. That made it work within the domain, and I confirmed I was getting back a header of Access-Control-Allow-Origin: “*” but when I would request from a different domain, I would still get an error that the Access-Control-Allow-Origin was not set on the server (even though it was). This happened with both Dojo and jQuery AJAX requests. I was finally able to solve the issue by adding these two headers together using the Dojo AJAX:

    headers: {
    ‘X-Requested-With’: null,
    ‘Content-Type’: ‘text/plain’
    },

    Note that in fact what I was requesting was not ‘text/plain’, it was ‘application/json’, but a JSON.parse(response) read it fine into a JSON object anyway, as expected. If I set the ‘Content-Type’ to ‘application/json’ however, it invoked a preflight request (I think) and the request failed. I’m a beginner to web programming, so that is a guess.