Pavel V.
Pavel V.

Reputation: 2790

Dojo.request for iteminfo - return code 200 in Fiddler but 0 in the browser

I use the same code for dojo.request as in a previous project, except for the URL address and the fact I'm calling service's iteminfo instead of layer's addFeatures. However, I always get the following error:

Unable to load http://foobar.com/arcgis/rest/services/MapServer/info/iteminfo status: 0

I confirmed this in Firefox and IE. The status shown by Firebug or Visual Studio is always 0, even though the status shown in Fiddler is 200. It shows 0 also when I mess something up and get 401 in Fiddler.

So, here's my code:

var promise = require('dojo/request').post(uri, {
    handleAs: "json",
    query: "f=pjson",        
    headers: {
        "X-Requested-With": null
    },
    //timeout: 60000,  //commenting this in and out changes nothing
    withCredentials: true
});

var res = promise.isResolved();
var rej = promise.isRejected();
var ful = promise.isFulfilled();
var can = promise.isCanceled();
var respres = promise.response.isResolved();
var resprej = promise.response.isRejected();
var respful = promise.response.isFulfilled();
var respcan = promise.response.isCanceled();

promise.response.then(
  //success
  function (response) {
    //something
  },
  //fail
  function (error) {
    //something different
  }
);

I want the output as a JSON, so I added the query option; without it, Fiddler shows the output as HTML instead. I found an answer indicating that the response may need time, but either it's not my case or something more complex than simple timeout option is needed.

All my test variables (res,rej...) hold false. So the request seems unresolved, unfulfilled etc. in the code, but Fiddler returns the response - I'm not skilled enough in these network arts to be able to draw conclusion from this, so I ask the question.

Also, I have a vague impression that some additional headers should be the solution. I've tried adding accept (nothing changed) and content-type (it went pre-flight and Fiddler reported status 401).

EDIT: the response header contains following security info:

Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Origin: http://localhost:30322 //origin for now
Access-Control-Allow-Origin: *

Upvotes: 1

Views: 354

Answers (2)

Pavel V.
Pavel V.

Reputation: 2790

I tried to preflight the request. The sent OPTIONS request seemed OK, but our server required authentication with it, leading to the error 401. I don't want to try to hack the OPTIONS request, so this is really solvable only server-side. As the purpose of all this is only testing and in production everything will be on that server or behind proxies, we decided to use some dirty workaround like having the JSON cached in a file for now.

For the mystery why Access-Control-Allow-Origin was not enough, I assume that POST might have been to blame. It's incompatible both with JSON-P and simple CORS requests. Plus, I've never got Access-Control-Allow-Methods response header, so their lack might have blocked the request. I'm not sure in this though.

Upvotes: 0

greenkarmic
greenkarmic

Reputation: 448

Browsers are getting more severe (for security reasons) about making cross-domain requests, and may simply refuse to load a cross-domain resource, even if it has a status of 200, and instead display 0. So if the domain in the uri you use in your dojo request is different from the domain in your site uri, this could be the problem.

Note that simply adding a port number qualifies has a different domain and will be considered a cross-domain request.

To work around this, you can either make all requests on your domain and add something in your dojo request uri to have your web server proxy the requests to the external server, ex:

    RewriteRule /arcgis/(.*)  http://foobar.com/arcgis/$1 [L,P]
    ProxyPassReverse /arcgis http://foobar.com/arcgis

Otherwise you have to manually specify that cross-domain requests from your site's domain are ok. The foobar.com server needs to add the HTTP header Access-Control-Allow-Origin with your domain value to the response and your browser will accept it. Adding the header Access-Control-Allow-Origin with a value of * will accept cross-domain requests from any domain, but is obviously less secure.

Upvotes: 1

Related Questions