Jeremy Raines
Jeremy Raines

Reputation: 1739

CORS: preflight passes, main request completes w/200, but browser still has Origin error

I am sending a CORS ajax request to a node server running express. In both the server logs and the js console, I can see that the preflight OPTIONS request succeeds.

Then, the main request also succeeds on the server and responds with a 200 and what I think are the correct headers. However, in Chrome, the networking tab reports the latter request as "cancelled" and the response is not accepted or processed:

XMLHttpRequest cannot load http://myserver.com/upload. Origin http://mysite.com is not allowed by Access-Control-Allow-Origin.

Here are the server logs with the headers printed out for both requests and responses:

76.79.201.210 - - [27/Jun/2013:23:23:17 +0000] "OPTIONS /upload HTTP/1.1" 204 0 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
START
{ host: 'localhost:5001',
  connection: 'close',
  'content-length': '109587',
  origin: 'http://mysite.com',
  'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36',
  'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryBZA4TATeeVWMHArH',
  accept: '*/*',
  referer: 'http://mysite.com/add',
  'accept-encoding': 'gzip,deflate,sdch',
  'accept-language': 'en-US,en;q=0.8' }
{ 'x-powered-by': 'Express',
  'access-control-allow-origin': '*',
  'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'access-control-allow-headers': 'X-Requested-With' }
XX.XX.XXX.210 - - [27/Jun/2013:23:23:19 +0000] "POST /upload HTTP/1.1" 200 118 "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
- - - [Thu, 27 Jun 2013 23:23:19 GMT] "POST /upload HTTP/1.0" 200 - "http://mysite.com/add" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"

Update: screenshot from Chrome's network tab -- the "cancelled" one is the one that was a 200 above

http://cl.ly/image/3c09330i1a17

Upvotes: 14

Views: 13559

Answers (3)

Nickolay Kutovoy
Nickolay Kutovoy

Reputation: 1

I had same issue, spent quite some time debugging...

I configured/debugged CORS server (nextjs app) reply, it was replying with 200 ok pre-flight OPTIONS, cleared browser (Chrome) cache nothing helped until I simply switched from using JS code like "const response = await fetch(" to "let res = axios.post(".

My issue was something to be with the client side library I was using in my RectJS app and the way it was making/handling HTTP/CORS.

Upvotes: 0

Brian Lewis
Brian Lewis

Reputation: 5729

Troubleshooting CORS-Related Problems

  • If you are trying to reproduce the problem, and you're not seeing a request/response, it is possible that your browser has cached an earlier failed preflight request attempt. Clearing your browser's cache may also clear the preflight cache...

https://developers.google.com/storage/docs/cross-origin

I tested the following configuration on test-cors.org and it appears to work. Just remember to clear your cache every now and then while you are troubleshooting.

var allowedHost = {
    // this is the origin that test-cors.org uses
    'http://client.cors-api.appspot.com': true
};

var allowCrossDomain = function(req, res, next) {
    if (!req.headers.origin || allowedHost[req.headers.origin]) {
        res.header('Access-Control-Allow-Credentials', true);
        res.header('Access-Control-Allow-Origin', req.headers.origin)
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
        res.header('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version');
        if (req.method == 'OPTIONS') res.send(200);
        else next();
    }
    else {
        res.send(403, {
            auth: false
        });
    }
}

Good luck!

Upvotes: 6

Jeremy Raines
Jeremy Raines

Reputation: 1739

So it turns out that because I had both nginx and express set up to respond with headers to the options request, it was somehow combining the Access-Control-Allow-Origin header value into "", "". I don't know if it read that as an array or what.

Still pretty baffled because 1) Why did the request make it past nginx? and 2) Why did the browser proceed with the POST if the OPTIONS headers were messed up?

Oh well, the lesson, as always -- Don't Repeat Yourself.

Upvotes: 0

Related Questions