I’m building a Backbone.js based app and face a strange issue.
At a certain point the app requests a collection resource and inside Chrome (and Safari) I get an error like that:
XMLHttpRequest cannot load http://api.mydomain.net/v1/foos/00000d/bars/000014/boots Origin http://localhost:3501 is not allowed by Access-Control-Allow-Origin.
Ok, CORS issue I thought and blamed my API. Then requested this very resource via CURL:
curl -i -H'Accept: application/json' -H'X-Auth-Token: pAWp5hrCmXA83GgFzgHC' -XOPTIONS 'http://api.mydomain.net/v1/foos/00000d/bars/000014/boots'
HTTP/1.1 200 OK
Status: 200
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Auth-Token
Content-Length: 0
looks good, now the GET:
curl -i -H'Accept: application/json' -H'X-Auth-Token: pAWp5hrCmXA83GgFzgHC' -XGET 'http://api.mydomain.net/v1/foos/00000d/bars/000014/boots'
HTTP/1.1 204 No Content
Status: 204
Cache-Control: no-cache
Content-Length: 0
Content-Type: text/plain
In case I request boots collection that contain at least one object, everything works fine. The CORS headers my server responds with arr totally fine as I think. So why do the browsers report a cross origin resource problem?
Is it due to the content type text/plain of my 204 responses?


You have to also include the
Access-Control-Allow-Originin the response headers of the second request. That’s not a client-side issue, but a backend one.This behaviour is in accordance with the CORS specification, applied in the following explanation (section 7.1.5 “Cross-Origin Request with Preflight”):
If the response has an HTTP status code of 301, 302, 303, or 307Not applicableIf the end user cancels the requestNot applicableIf there is a network errorNot applicablePerform a resource sharing check. If it returns fail, apply the cache and network error steps.
Your request already fails at the first step of the resource sharing check:
Access-Control-Allow-Originheader values, return fail and terminate this algorithm.I provide a simple NodeJS example illustrating your problem.
Your current backend behaves like:
Now, make the request and experience a failure:
Go back to the code I provided, and enable the
Access-Control-Allow-Originheader in the response, and test again. Your request will now succeed.