It looks like according to the CORS Spec, GET and POST requests should transparently follow 302 redirects. But Chrome is canceling my request.
Here's the JS that does the request:
var r = new XMLHttpRequest(); r.open('GET', 'https://dev.mysite.com/rest', true); r.send();
Here's what should happen:
But after step 2, Chrome cancels the request. If there was no HTTP 302, the request would work perfectly. I've confirmed this.
When the request runs, I can see in Chrome's Network panel only one XHR -- a canceled POST request with no response headers or response body.
Debugging with Chrome's net-internals tool, I see that there was a response sent from the server, and after that, the request was cancelled. Here is the output of the request:
79295: URL_REQUEST https://dev.mysite.com/rest Start Time: 2013-08-30 12:41:11.637 t=1377880871637 [st= 0] +REQUEST_ALIVE [dt=13455] t=1377880871638 [st= 1] URL_REQUEST_BLOCKED_ON_DELEGATE [dt=1] --> delegate = "extension Adblock Plus" t=1377880871639 [st= 2] +URL_REQUEST_START_JOB [dt=13453] --> load_flags = 143540480 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT) --> method = "POST" --> priority = 2 --> upload_id = "0" --> url = "https://dev.mysite.com/rest" t=1377880871639 [st= 2] HTTP_CACHE_GET_BACKEND [dt=0] t=1377880871639 [st= 2] +HTTP_STREAM_REQUEST [dt=7] t=1377880871646 [st= 9] HTTP_STREAM_REQUEST_BOUND_TO_JOB --> source_dependency = 79296 (HTTP_STREAM_JOB) t=1377880871646 [st= 9] -HTTP_STREAM_REQUEST t=1377880871646 [st= 9] +HTTP_TRANSACTION_SEND_REQUEST [dt=0] t=1377880871646 [st= 9] HTTP_TRANSACTION_SEND_REQUEST_HEADERS --> GET /facultyportfolio-rest HTTP/1.1 Host: dev.liberty.edu Connection: keep-alive Content-Length: 46 Origin: http://localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36 Content-Type: application/json; charset=UTF-8 Accept: */* Referer: http://localhost:8080/ajaxtest.html Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 t=1377880871646 [st= 9] HTTP_TRANSACTION_SEND_REQUEST_BODY --> did_merge = true --> is_chunked = false --> length = 46 t=1377880871646 [st= 9] -HTTP_TRANSACTION_SEND_REQUEST t=1377880871646 [st= 9] +HTTP_TRANSACTION_READ_HEADERS [dt=1001] t=1377880871646 [st= 9] HTTP_STREAM_PARSER_READ_HEADERS [dt=1000] t=1377880872646 [st= 1009] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 302 Found Date: Fri, 30 Aug 2013 16:41:11 GMT Server: Apache/2 Access-Control-Allow-Origin: http://localhost:8080 Access-Control-Allow-Credentials: true Location: https://dev.mysite.com/rest/ Content-Language: en-US Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 20 Connection: close Content-Type: text/plain; charset=UTF-8 t=1377880872647 [st= 1010] -HTTP_TRANSACTION_READ_HEADERS t=1377880872647 [st= 1010] +URL_REQUEST_BLOCKED_ON_DELEGATE [dt=12445] t=1377880885091 [st=13454] CANCELLED t=1377880885092 [st=13455] -URL_REQUEST_START_JOB --> net_error = -3 (ERR_ABORTED) t=1377880885092 [st=13455] -REQUEST_ALIVE
At the end, you can see "Cancelled" because of "URL_REQUEST_BLOCKED_ON_DELEGATE". I don't know what that means. But again, if there was no HTTP 302 redirect, the error would not occur.
Does anyone know what is causing Chrome to cancel this request?
You can follow these five steps to fix HTTP 302 errors on your website: Determine whether the redirects are appropriate or not by examining the URLs that are issuing the 302 redirects. Check your plugins to make sure any redirect settings are valid. Ensure that your WordPress URL settings are configured correctly.
Simple CORS requests will follow redirects. Preflight requests will not follow redirects. If the redirect is to the same server as the original request, the Origin header will stay the same. Otherwise, the Origin header will be set to null .
What is an HTTP 302? The 302 status code is a redirection message that occurs when a resource or page you're attempting to load has been temporarily moved to a different location. It's usually caused by the web server and doesn't impact the user experience, as the redirect happens automatically.
What Is A 302 Redirect? A 302 redirect lets search engines know that a website or page has been moved temporarily. When Should You Use 302 Redirects? Use this type of redirect if you want to send users to a new site or page for a short period of time, such as when you're redesigning or updating your website.
The answers in here are mixed, hinting on certain settings in code etc. which may solve the redirect problem with CORS, but the CORS spec clearly specifies when such CORS redirects will fail/pass : As per the spec, browsers should
If the manual redirect flag is unset and the response has an HTTP status code of 301, 302, 303, 307, or 308 Apply the redirect steps
If the response has an HTTP status code of 301, 302, 303, 307, or 308 Apply the cache and network error steps.
I have explored various CORS scenarios in github repo: https://github.com/monmohan/cors-experiment.
This specific issue with failed redirect can also be easily reproduced in isolation by the bundle here: https://github.com/monmohan/cors-experiment/tree/master/issue
I found this post about setting the correct Access-Control-Allow-Origin CORS header on your 302 response to be helpful, at least in my similar-sounding case.
Investigation of the problem showed that his XHR was not landing on the CORS-enabled URL directly, but was being redirected to it through an HTTP 302 (redirect) response.
So bear in mind that the redirecting URL must also include an Access-Control-Allow-Origin header, else the browser will stop right there with its attempted cross-domain request.
I've also found that setting additional CORS headers above and beyond Access-Control-Allow-Origin will often result in a cancelled transaction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With