Jim Wharton
Jim Wharton

Reputation: 1415

Dojo can't make a CORS request. jQuery can

I've setup a dojo module to handle my communication:

define(["dojo/request/xhr", "dojo/json"],
  function(xhr, JSON) {

  return {
    getJson: function(url) {
      return xhr.get(url, {handleAs:'json', headers: {"X-Requested-With": ""}});
    },
    postJson: function(url, postData) {
      return xhr(url, {
        method: 'POST',
        handleAs: "json",
        data: JSON.stringify(postData),
        headers: {"X-Requested-With": "", "Content-Type":"application/json"}
      })
    },
    getSecure: function(url, token) {
      return xhr.get(url, {handleAs:'json', headers: {"X-AUTH": token, "X-Requested-With": "", "Content-Type":"application/json" }});
    },
    postSecure: function(url, postData, token) {
      return xhr(url, {
        method: 'POST',
        handleAs: 'json',
        data: JSON.stringify(postData),
        headers: {"X-Requested-With": "", "Content-Type":"application/json", "X-AUTH": token}
      });
    }
  };

});

While sending a request, OPTIONS fails almost immediately. I tried the request in Postman just to make sure the API was alive and well. Then I got a wild hair and built a quick test in jQuery:

$.ajax({
  url: 'https://someurl.url/auth/get_token',
  type: 'post',
  data: JSON.stringify({username:"user", password:"pass"}),
  contentType: 'application/json',
  dataType: 'json' ,
  xhrFields: {
    withCredentials: false
  },
  success: function(json) {
    console.log(json);
    $.ajax({
      url: 'https://someurl.url/api/service/' + json.results.somevalue,
      type: 'GET',
      headers: { 'X-AUTH': json.results.token },
      contentType: 'application/json; charset=utf-8',
      dataType: 'json' ,
      success: function(json) {
        console.log(json);

      },
      error: function (XMLHttpRequest, textStatus, errorThrown) {
        console.log("error :"+XMLHttpRequest.responseText);
      }


    });

  },
  error: function (XMLHttpRequest, textStatus, errorThrown) {
    console.log("error :"+XMLHttpRequest.responseText);
  }

That works just fine. I know that Dojo was having problems a year or so ago with sending the 'X-Requested-width' header, but I've nulled that out and it's not attempting to send it. I'm pulling my hair out as I really don't want to include jQuery as a dependency to my app just for making web requests. Dojo SHOULD be able to do this. Any Dojo people out there have any idea how to make this work?

Upvotes: 3

Views: 5512

Answers (4)

Anil Agrawal
Anil Agrawal

Reputation: 3026

You can simply use dojo/request/xhr module to make any HTTP request like OPTIONS, GET, PUT, DELETE, CONNECT, PUT, HEAD, TRACE etc.

Pass http method name as a string (all in capitals) as below,

require(['dojo/request/xhr'], function(xhr){
    xhr(url, {
        handleAs : "json",
        method : 'OPTIONS',
        data : formDataAsJson,
        headers : {
            'Content-Type' : 'application/json'
        }
    }).then(
        function(data) {
            console.log("response data is: "+ JSON.stringify(data));
        },
        function(err) {
            console.log("The err is: "+ JSON.stringify(err));
        },
        function(evt) {
            console.log("The evt is: "+ JSON.stringify(evt));
        }
    );
});

Upvotes: 0

Sudhirkumar Murkute
Sudhirkumar Murkute

Reputation: 197

          var syncCall = true;
          if(dojo.isFF)
            syncCall = false;
          xhr(url, { 
            method : 'GET',
            handleAs : 'json',
            withCredentials : true,
            sync  :  syncCall,
            headers : {
              'X-XSRF-Token' : settings.XSRF_TOKEN,
              'Content-Type' : 'application/json'
            }

Upvotes: 0

Zack Stauber
Zack Stauber

Reputation: 76

I had a similar experience with dojo.xhrGet, and 'Content-Type': 'application/json' was the problem. I had to change it to pretend I was getting back plain text for it to actually work cross domain, thus:

dojo.xhrGet({
    url: url,
    headers: {
        'X-Requested-With': null,
        'Content-Type': 'text/plain'
    },
    load: function(responseText) {
        var results = JSON.parse(responseText);
    ...
    }
});

After that it worked cross domain, and it treated results as a JSON object.

Upvotes: 3

C Snover
C Snover

Reputation: 18766

Empty string is not the same thing as null. You need to set X-Requested-With to null, not "", to avoid a preflight request. It shouldn’t matter, unless your server is not responding allowing an X-Requested-With header, since you are sending a custom header anyway which will always trigger preflight.

Upvotes: 3

Related Questions