Triggering an AJAX GET
to http://qualifiedlocalhost:8888/resource.json
kicks off the expected CORS pre-flight, which looks like it comes back correctly:
OPTIONS
request Request URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
Response Headers
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express
So it should work, right?
But the subsequent request still fails with the error XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
XMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
Request URL:http://qualifiedlocalhost:8888/resource.json
Request Headers
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest
Maybe it's staring right in front of me. But, any ideas? Just in case it's relevant... I'm using an AngularJS $resource
and talking to a CompoundJS server.
change your Access-Control-Allow-Methods: 'GET, POST' to 'GET, POST, PUT, DELETE'
before:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
After:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
I recently had the same issue . The problem is that the Access-Control-Allow-Origin
header (and, if you use it, the Access-Control-Allow-Credentials
header) must be sent in both the preflight response and the actual response.
Your example has it only in the preflight response.
Is your web server/get function ALSO including the HTTP header: Access-Control-Allow-Origin? I eventually found success with that addition, using AngularJS 1.0.7 and a remote Java servlet. Here is my Java code snippet--no changes were required in AngularJS client:
Servlet:
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Send Response
super.doOptions(request, response);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* ... */
response.setHeader("Access-Control-Allow-Origin", "*");
}
A more elegant alternative is a servlet filter.
We have been noticing the same issue, where the server is sending the correct CORS headers, but the browser fails because it thinks the CORS requirements are not being met. More interestingly, in our case, it only happens on some AJAX calls in the same browser session, but not all.
Clearing the browser cache solves the problem in our case -- My current working theory is that this has something to do with cookies being set by the cross origin server. I noticed in your scenario, there is a cookie being set as part of the response to the pre-flight OPTIONS request. Have you tried making that server not set any cookies for requests coming from a different origin?
However, we've noticed that in some cases, the problem re-appeared after resetting the browser. Also, running the browser in in-private mode causes the problem to go away, pointing to some problem to do with what's in the browser cache.
For reference, here is my scenario (I almost posted this as a new question in SO, but putting it here instead):
We ran into a bug where some CORS GET requests made via jQuery.ajax were failing. In a given browser session, we see the pre-flight OPTIONS request go through, followed by the actual request. In the same session, some requests go through and others fail.
The sequence of requests and responses in the browser network console look like below:
First the OPTIONS pre-flight request
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Which gets a response like,
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Then the actual GET request,
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
Which gets an error in the browser console like,
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
Additional Debugging
I can replay the same sequence via curl, and I see valid responses coming from the server. ie they have the expected CORS headers that should let the requests go through.
Running the same scenario in an in-private / incognito browser window did not reproduce the problem. This lead me to try clearing the cache, and that made the problem go away too. But after a while, it came back.
The issue was reproducing on iPhone safari as well as on Chrome on OSX desktop.
What I really need help with
I'm suspecting there are some cookies set in the cross-origin domain that are getting involved here and potentially exposing a bug in the browser. Are there tools or breakpoints I can set in the browser (native stack?) to try and debug this further? A breakpoint in the code that evaluates the CORS policy would be ideal.
Looks like your response to 'options' is working fine. The problem seems to be in the 'get' response.
You'll want to have your 'get' response return the same CORS headers as the 'options' response.
In particular, 'get' response should include
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
use cors module to avoid the problem
var cors = require('cors')
var app = express()
app.use(cors())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.