Ok, so this is a weird one.
I am working on a php script that does a lot of work when requested (image processing). So this is not unusual it issues a response in 10 seconds, up to 30 seconds sometimes : it's a long script, and this is important for the next part.
While logging the image processing code, I noticed that processes that should be called only once were called twice.
The reason : Chrome is cancelling the first request after 3s, then requests the same URL again.
The sequence is always the same.
URL requested
Cancel after 3 seconds sharp
Auto-reload with http scheme
307 due to HSTS on our server
URL requested again with https
This one loads correctly
The cancelled request is shown as Stalled in "Timing" tab.
This is only happening in Chrome (92.0.4515.107 for me). I don't see this behavior in Firefox.
Now how can one reproduce this witchcraft ? Easy, I can reproduce on 2 different servers on 2 different providers (GCE, and OVH) and it has a weird link with the duration of the initial request to this URL.
Create a new php script on your webserver only containing
<?php sleep(10); echo 'Done'; ?>
Call your script URL in Chrome
The first call will succeed
But all the next calls will certainly trigger "the sequence"
By checking on Chrome logs, I came to think this has a link with HTTP2_SESSION
t=235805 [st= 5] +HTTP_TRANSACTION_SEND_REQUEST [dt=1]
t=235806 [st= 6] HTTP_TRANSACTION_HTTP2_SEND_REQUEST_HEADERS
--> :method: GET
:authority: my.server.com
:scheme: https
:path: /admin/ot/test1.php
pragma: no-cache
cache-control: no-cache
authorization: [38 bytes were stripped]
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
cookie: [409 bytes were stripped]
t=235806 [st= 6] -HTTP_TRANSACTION_SEND_REQUEST
t=235806 [st= 6] +HTTP_TRANSACTION_READ_HEADERS [dt=3012]
t=238818 [st=3018] CANCELLED
t=238818 [st=3018] -REQUEST_ALIVE
On the URL_REQUEST above, we don't learn much. We just see "CANCELLED" after 3s.
But the HTTP2_SESSION shows a strange error :
27185: HTTP2_SESSION
my.server.com:443 (DIRECT)
Start Time: 2021-07-22 17:13:09.460
t=222444 [st= 0] +HTTP2_SESSION [dt=28616+]
--> host = "my.server.com:443"
--> proxy = "DIRECT"
t=222444 [st= 0] HTTP2_SESSION_INITIALIZED
--> protocol = "h2"
--> source_dependency = 27181 (SOCKET)
t=222445 [st= 1] HTTP2_SESSION_SEND_SETTINGS
--> settings = ["[id:1 (SETTINGS_HEADER_TABLE_SIZE) value:65536]","[id:3 (SETTINGS_MAX_CONCURRENT_STREAMS) value:1000]","[id:4 (SETTINGS_INITIAL_WINDOW_SIZE) value:6291456]","[id:6 (SETTINGS_MAX_HEADER_LIST_SIZE) value:262144]"]
t=222445 [st= 1] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 15663105
--> window_size = 15728640
t=222445 [st= 1] HTTP2_SESSION_SEND_WINDOW_UPDATE
--> delta = 15663105
--> stream_id = 0
t=222446 [st= 2] HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = true
--> has_priority = true
--> :method: GET
:authority: my.server.com
:scheme: https
:path: /admin/ot/test1.php
pragma: no-cache
cache-control: no-cache
authorization: [38 bytes were stripped]
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
cookie: [409 bytes were stripped]
--> parent_stream_id = 0
--> source_dependency = 27179 (HTTP_STREAM_JOB)
--> stream_id = 1
--> weight = 256
t=222471 [st= 27] HTTP2_SESSION_RECV_SETTINGS
t=222471 [st= 27] HTTP2_SESSION_SEND_SETTINGS_ACK
t=222471 [st= 27] HTTP2_SESSION_RECV_SETTING
--> id = "3 (SETTINGS_MAX_CONCURRENT_STREAMS)"
--> value = 100
t=222471 [st= 27] HTTP2_SESSION_UPDATE_STREAMS_SEND_WINDOW_SIZE
--> delta_window_size = 983041
t=222471 [st= 27] HTTP2_SESSION_RECV_SETTING
--> id = "4 (SETTINGS_INITIAL_WINDOW_SIZE)"
--> value = 1048576
t=222471 [st= 27] HTTP2_SESSION_RECV_SETTING
--> id = "6 (SETTINGS_MAX_HEADER_LIST_SIZE)"
--> value = 65536
t=222471 [st= 27] HTTP2_SESSION_RECV_WINDOW_UPDATE
--> delta = 983041
--> stream_id = 0
t=222471 [st= 27] HTTP2_SESSION_UPDATE_SEND_WINDOW
--> delta = 983041
--> window_size = 1048576
t=222471 [st= 27] HTTP2_SESSION_RECV_SETTINGS_ACK
t=232550 [st=10106] HTTP2_SESSION_RECV_HEADERS
--> fin = false
--> :status: 200
date: Thu, 22 Jul 2021 15:13:09 GMT
vary: Accept-Encoding
content-encoding: gzip
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-ua-compatible: IE=Edge
x-frame-options: sameorigin
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
content-length: 24
content-type: text/html; charset=CP1252
cache-control:
age: 0
x-cache: NOT CACHABLE
accept-ranges: bytes
via: 1.1 google
alt-svc: clear
--> stream_id = 1
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -1
--> window_size = 15728639
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 1
--> window_size = 15728640
t=232550 [st=10106] HTTP2_SESSION_RECV_DATA
--> fin = false
--> size = 24
--> stream_id = 1
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -24
--> window_size = 15728616
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -110
--> window_size = 15728506
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 110
--> window_size = 15728616
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -1
--> window_size = 15728615
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 1
--> window_size = 15728616
t=232550 [st=10106] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -71
--> window_size = 15728545
t=232551 [st=10107] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 71
--> window_size = 15728616
t=232551 [st=10107] HTTP2_SESSION_RECV_DATA
--> fin = true
--> size = 0
--> stream_id = 1
t=232551 [st=10107] HTTP2_SESSION_PING
--> is_ack = false
--> type = "received"
--> unique_id = 0
t=232551 [st=10107] HTTP2_SESSION_PING
--> is_ack = true
--> type = "sent"
--> unique_id = 0
t=232552 [st=10108] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 24
--> window_size = 15728640
t=235806 [st=13362] HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = true
--> has_priority = true
--> :method: GET
:authority: my.server.com
:scheme: https
:path: /admin/ot/test1.php
pragma: no-cache
cache-control: no-cache
authorization: [38 bytes were stripped]
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
cookie: [409 bytes were stripped]
--> parent_stream_id = 0
--> source_dependency = 27212 (HTTP_STREAM_JOB)
--> stream_id = 3
--> weight = 256
t=238818 [st=16374] HTTP2_SESSION_SEND_RST_STREAM
--> description = ""
--> error_code = "8 (CANCEL)"
--> stream_id = 3
t=238846 [st=16402] HTTP2_SESSION_SEND_HEADERS
--> exclusive = true
--> fin = true
--> has_priority = true
--> :method: GET
:authority: my.server.com
:scheme: https
:path: /admin/ot/test1.php
pragma: no-cache
cache-control: no-cache
authorization: [38 bytes were stripped]
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site: none
sec-fetch-mode: navigate
sec-fetch-user: ?1
sec-fetch-dest: document
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?0
accept-encoding: gzip, deflate, br
accept-language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
cookie: [409 bytes were stripped]
--> parent_stream_id = 0
--> source_dependency = 27225 (HTTP_STREAM_JOB)
--> stream_id = 5
--> weight = 256
t=249924 [st=27480] HTTP2_SESSION_RECV_HEADERS
--> fin = false
--> :status: 200
date: Thu, 22 Jul 2021 15:13:25 GMT
vary: Accept-Encoding
content-encoding: gzip
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-ua-compatible: IE=Edge
x-frame-options: sameorigin
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
content-length: 24
content-type: text/html; charset=CP1252
cache-control:
age: 0
x-cache: NOT CACHABLE
accept-ranges: bytes
via: 1.1 google
alt-svc: clear
--> stream_id = 5
t=249924 [st=27480] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -1
--> window_size = 15728639
t=249924 [st=27480] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 1
--> window_size = 15728640
t=249924 [st=27480] HTTP2_SESSION_RECV_DATA
--> fin = false
--> size = 24
--> stream_id = 5
t=249924 [st=27480] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -24
--> window_size = 15728616
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -94
--> window_size = 15728522
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 94
--> window_size = 15728616
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -1
--> window_size = 15728615
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 1
--> window_size = 15728616
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = -104
--> window_size = 15728512
t=249925 [st=27481] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 104
--> window_size = 15728616
t=249925 [st=27481] HTTP2_SESSION_RECV_DATA
--> fin = true
--> size = 0
--> stream_id = 5
t=249925 [st=27481] HTTP2_SESSION_PING
--> is_ack = false
--> type = "received"
--> unique_id = 2
t=249925 [st=27481] HTTP2_SESSION_PING
--> is_ack = true
--> type = "sent"
--> unique_id = 2
t=249927 [st=27483] HTTP2_SESSION_UPDATE_RECV_WINDOW
--> delta = 24
--> window_size = 15728640
Walkthrough :
Initial request (the one that worked) starts at st=0, ends at st=10106 (10 seconds of sleep)
The second request (the one that gets automatically cancelled) starts at st=13362, ends at st=16374 (3s later) with this
t=238818 [st=16374] HTTP2_SESSION_SEND_RST_STREAM
--> description = ""
--> error_code = "8 (CANCEL)"
--> stream_id = 3
Then the request gets reloaded at st=16402, and finally gets back at st=27480 with its 10s sleep delay
I honestly don't know what to do with this. This can be reproduced easily but I can't figure out why it happens.
Chrome is largely used in my company for our internal tools, so I'm bugged it reloads heavy processing URL 2 times in a row for mysterious reasons.
Any help would be greatly appreciated.
OH, and I did disable every extensions I have. It does not help. I don't see any mention to any extension intervention in Chrome logs anyway.
I think this problem can be reproduced on any domain which responses with longer than 3s delay and with any technology at the server side. I suppose this is a chrome issue. I reproduced it with ASP.net MVC and AWS Beanstalk hosting. I also reproduced it differently on https://example.com/ when you throttle connection to get slower response times.
To reproduce it (on Chrome Version 92.0.4515.159 (Official Build) (64-bit)):
Open Dev Tools and add Very Slow Network Throttling Profile as follows
go to url by pasting: https://example.com/ -> this should work
refresh page by pressing F5 -> this should work as well
now, very important, just click the address bar twice so you can see:
and then press enter. Now chrome behaves differently and first it tries the https url and if there is no response within 3s it redirects to http. The cancelled request is the one I am talking about.
Maybe this will help sb resolving the issue.
For the same problem, I didn't find such a problem when I used Firefox. At first, I suspected that it was a server-side configuration problem. Later, I found that the problem remained after changing the environment. Finally, it was located on the browser side, but I don't know what the specific reason is
If your server don't support https, please try to enter 'http://' to specify the protocol for each request. Otherwise Chrome tries https automatically. It takes 3 seconds, and then go http.
Related
I have the following setup:
Webserver 1 https://localhost:8888
Webserver 2 https://localhost:9005
Webserver 3 https://localhost:9006
I open https://localhost:8888 from a Web browser and enter the following JS code.
(async () => {
const endpointId = '1d60eb5195725648';
const continueUrl = 'https://localhost:9006/'
const signinUrl = new URL('https://localhost:9005/_login');
signinUrl.searchParams.set('continue', continueUrl);
signinUrl.searchParams.set('endpoint', endpointId);
const response = await fetch(signinUrl.toString(), {
credentials: 'include',
headers: {
'Authorization': `Bearer ${gapi.auth.getToken().access_token}`,
},
});
})();
I'm getting this error in my Chrome Browser Version 102.0.5005.115
Access to fetch at 'https://localhost:9006/?TOKEN=0<Truncated>c&endpoint=1d60eb5195725648' (redirected from 'https://localhost:9005/_login?continue=https%3A%2F%2Flocalhost%3A9006%2F&endpoint=1d60eb5195725648') from origin 'https://localhost:8888' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://localhost:8888' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Looks like Origin field is correct according to the info in Headers. What am I missing?
(I truncated Token to improve readability)
Requests:
Request URL: https://localhost:9005/_login?continue=https%3A%2F%2Flocalhost%3A9006%2F&endpoint=1d60eb5195725648
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: [::1]:9005
Referrer Policy: origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Headers: Proxy-Authorization
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: https://localhost:8888
Content-Length: 0
Date: Sun, 12 Jun 2022 02:47:09 GMT
--
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,es;q=0.8
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: GET
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:9005
Origin: https://localhost:8888
Pragma: no-cache
Referer: https://localhost:8888/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
Request URL: https://localhost:9005/_login?continue=https%3A%2F%2Flocalhost%3A9006%2F&endpoint=1d60eb5195725648
Request Method: GET
Status Code: 302 Found
Remote Address: [::1]:9005
Referrer Policy: origin
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://localhost:8888
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 360
Content-Type: text/html; charset=utf-8
Date: Sun, 12 Jun 2022 02:47:09 GMT
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Location: https://localhost:9006/?TOKEN=00cfdab4e480656ed7d71b3e58df42fe5422d85d33118a5af5fb7cc66f2d81330b46740ccbca4927ecfe841e751f0de72fdf53c4eb7d66b7c5ab857e33c6beaa270950fe0c49047fd5260db3120731d0abbfe3be1a0d316db4b0754610c81e2b070cea24e46e0e5ef76937c65832ef7c315b452b846e87f59be3124478cee49045162c&endpoint=1d60eb5195725648
Pragma: no-cache
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,es;q=0.8
Authorization: Bearer ya29.a0ARrdaM8mfOksOCl6l4O13z5PQv1cUVgKDKWgbo_rNXDL_Fw_-aedVVJdAFOSYByUjEy1WYrAKoik0KHx_c69aCXZcuAXbYedYkZRtDb5Y3Bz98eqjrOBjT0XrWspWdGNqRvsq_L_rDERdnsUFDFKCNiFCHV4sg
Cache-Control: no-cache
Connection: keep-alive
Cookie: _ga=GA1.1.1057744305.1654277711; _gid=GA1.1.1514740287.1654641546; _gat=1
Host: localhost:9005
Origin: https://localhost:8888
Pragma: no-cache
Referer: https://localhost:8888/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="102", "Google Chrome";v="102"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
Request URL: https://localhost:9006/?TOKEN=00cfdab4e480656ed7d71b3e58df42fe5422d85d33118a5af5fb7cc66f2d81330b46740ccbca4927ecfe841e751f0de72fdf53c4eb7d66b7c5ab857e33c6beaa270950fe0c49047fd5260db3120731d0abbfe3be1a0d316db4b0754610c81e2b070cea24e46e0e5ef76937c65832ef7c315b452b846e87f59be3124478cee49045162c&endpoint=1d60eb5195725648
Referrer Policy: origin
Provisional headers are shown
Learn more
Referer: https://localhost:8888/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
I set max-age in Cache-Control header, but every time when I reload the webpage, it just goes out and fetches the resource again, following is an example request and response headers:
Request Headers
:authority: mydomain.com
:method: GET
:path: /.well-known/openid-configuration
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: en
cache-control: max-age=0 // I have no idea why this is sent in request by chrome
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: none
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Response Headers
access-control-allow-credentials: true
cache-control: public, s-maxage=2678400, max-age=14400, immutable
cf-cache-status: DYNAMIC
cf-ray: 6e7465234fc16c30-SIN
content-encoding: br
content-type: application/json; charset=utf-8
date: Sat, 05 Mar 2022 16:58:12 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=dSVocqHdnD4mopGV2L7pD08hRF3MZbpmBAsNHWm2eBznl15JNgOU7bkNcBn4qgoszBpGpGoCBPSbgCLWq796dv0jta9Ajlwq0BCEyW55h3Q2NO7mfQuz8cABZLAgWam4"}],"group":"cf-nel","max_age":604800}
server: cloudflare
vary: Origin, Accept-Encoding
I am having trouble with Chromium-based browsers and CORS requests that
include 302 redirects. More specifically, I am having trouble with Chromium
versions 34-42 inclusive; 43 and later works, and it seems 33 and earlier
versions worked as well (I didn't test too far past 33, 28 worked).
My XHR request uses withCredentials=true, so Access-Control-Allow-Origin="*"
is not allowed; the server must reply with an Access-Control-Allow-Origin
header that echoes the incoming request's Origin header.
After receiving the first 302, Chromium 43 and later sends "Origin: null" as
part of the redirected request, and accepts 'Access-Control-Allow-Origin: null"
in response (as does Firefox).
The Chromium series of 34-42 all send the host name as Origin for all requests,
and several issues from this time indicate that CORS redirects were only
supported with Access-Control-Allow-Origin set to "*", and that "the original
XHR must not have allow-credentials set to true", example:
https://code.google.com/p/chromium/issues/detail?id=154967
I am hoping this is a misconception, and there is something as an app
developer I can do on the client and/or server to coerce those versions to
not cancel the redirect, or failing that, ideas for a workaround.
Version 33 & earlier sent the entire host name for every request, and the full
roundtrip works.
One possibility for a workaround I have been experimenting with stems from the
fact that, I actually do not need withCredentials=true for the cross-domain
request, I only need it for the redirect back to the origin host to exchange
cookie-based authentication for an access_token, but I could not find a way to
get the client to send a cookie when following the 302 to itself unless it was
also sent with the original cross-domain request.
To illustrate, here are excerpts from a chrome://net-internals/#events log for
a successful request using Chrome 43:
[img src]
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg?timestamp=1437075435614 HTTP/1.1
Host: media-qa.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1568 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Content-Type: text/html; charset=utf-8
Location: https://qa-app.example.com/oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437075435614
[get cross-domain access token]
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437075435614 HTTP/1.1
Host: qa-app.example.com
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1762 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-HTTP-Method-Override, X-Requested-With
Access-Control-Allow-Origin: null
Content-Type: text/html; charset=utf-8
Location: https://media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?timestamp=1437075435614&access_token=L221i4rC5R8NY2AbP4lIxo7apr6HlIHttKroKkQi3tzUSaL7NE7aoBcLUI432Mast8b/NH7ksFfRhsCOhK7P86Lc4C9GlkRn%2Bze/UBJeG8gbRVlnxdjdzBFfp9kAbYR9onDM9b1bUdRaV1q19it8OL3aBzThrmng1E%2BMmT%2BVyK0qXLqQ6yA/tHfrgyC9XwFbKqW6BQSpLOyVOPHZZ4t3dgzimTD9HJCbLUUjZt7nf7iCAOBcaR9CiUH8vlcP4wkOmXk3AoDslYu6IUZtRHrSs7OplBtTXgmzBlSaum%2BccFzdNu5TuH%2BQkmp2QQHErwRJkUNN9S5ZcRzlXdUGg8%2B698Wh5zYFVa%2B/pEfykkf%2BAuqKjbVicGq%2BgxCYOCuqe4YJU/GPMHsBC6gvVYFmtkDaG4za1N4fvbmBb9u%2BHHZNdW0kvj55N9QgJ86lHZjddvfEivET0TVTo1u0u6Wp/TM4EMXLtMK3urBpEAMWBT9PlE8%3D
[url redirection service adds cloudfront signature]
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?timestamp=1437075435614&access_token=L221i4rC5R8NY2AbP4lIxo7apr6HlIHttKroKkQi3tzUSaL7NE7aoBcLUI432Mast8b/NH7ksFfRhsCOhK7P86Lc4C9GlkRn%2Bze/UBJeG8gbRVlnxdjdzBFfp9kAbYR9onDM9b1bUdRaV1q19it8OL3aBzThrmng1E%2BMmT%2BVyK0qXLqQ6yA/tHfrgyC9XwFbKqW6BQSpLOyVOPHZZ4t3dgzimTD9HJCbLUUjZt7nf7iCAOBcaR9CiUH8vlcP4wkOmXk3AoDslYu6IUZtRHrSs7OplBtTXgmzBlSaum%2BccFzdNu5TuH%2BQkmp2QQHErwRJkUNN9S5ZcRzlXdUGg8%2B698Wh5zYFVa%2B/pEfykkf%2BAuqKjbVicGq%2BgxCYOCuqe4YJU/GPMHsBC6gvVYFmtkDaG4za1N4fvbmBb9u%2BHHZNdW0kvj55N9QgJ86lHZjddvfEivET0TVTo1u0u6Wp/TM4EMXLtMK3urBpEAMWBT9PlE8%3D HTTP/1.1
Host: media-qa.example.com
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1568 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, X-Requested-With
Access-Control-Allow-Origin: null
Content-Type: text/html; charset=utf-8
Location: https://gbbrsh.cloudfront.net/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?Expires=1437075499&Signature=RpCVix5lcF5~Arah0WxhSoB3SN7ZfxXIwnaL8EOdlslIz5c9Ycic1wF~sjwTnWD5fxS~SBhexIz37oqjHjED3MTPiXAmuPjO1mQ-V8ACc8N-geWBIvMQRw9kCjCRmtquSs7TynaFqopv0BpQKH2G1xVdfoDaOZZWso7pXnpR50c2NdyDD-WMZNLKJ657Dj4-wCL8ZJdUPOgiXsfcxM1AZGy5P034SCL8JB8ZyEh1bUDszLkQa8lIpsy08mt9t8ZjFcR2i6bqBZNZOquT3jbOEy8VprL4lmtyOmVJaNTaBevZC6rQ6CM~jd~Ya2FockK5bNGYxM043OU71NExS0lHTg__&Key-Pair-Id=APKAJNUAAHKHVOSPPXTQ
Set-Cookie: [349 bytes were stripped]
[finally, get cloudfront image]
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?Expires=1437075499&Signature=RpCVix5lcF5~Arah0WxhSoB3SN7ZfxXIwnaL8EOdlslIz5c9Ycic1wF~sjwTnWD5fxS~SBhexIz37oqjHjED3MTPiXAmuPjO1mQ-V8ACc8N-geWBIvMQRw9kCjCRmtquSs7TynaFqopv0BpQKH2G1xVdfoDaOZZWso7pXnpR50c2NdyDD-WMZNLKJ657Dj4-wCL8ZJdUPOgiXsfcxM1AZGy5P034SCL8JB8ZyEh1bUDszLkQa8lIpsy08mt9t8ZjFcR2i6bqBZNZOquT3jbOEy8VprL4lmtyOmVJaNTaBevZC6rQ6CM~jd~Ya2FockK5bNGYxM043OU71NExS0lHTg__&Key-Pair-Id=APKAJNUAAHKHVOSPPXTQ HTTP/1.1
Host: gbbrsh.cloudfront.net
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 200 OK
Content-Length: 48776
Access-Control-Allow-Origin: null
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin
And here is an unsuccessful log using version 42, note that all the redirects
using 43 above sent "Origin: null", but 42 sends the host name (which the
server replies with), and the client cancels the request:
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg?timestamp=1437074740624 HTTP/1.1
Host: media-qa.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1571 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Location: https://qa-app.example.com/oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437074740624
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437074740624 HTTP/1.1
Host: qa-app.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1769 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-HTTP-Method-Override, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Location: https://media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?timestamp=1437074740624&access_token=JbXemck/weq2TjoVtgwuXDZB1GgmBqlDix3z5WfsWFlf2aZVmCud99wtAU%2BBErVxm6Lk1MRP1ubM/bf59URPs9uXMLYC%2Bnk6lAYQRUBhO3UmBnZk967W/5f9/1YnfRHQe1Y9fGRSkddQJdzdOwkMAvYSCw%2BN1ofkrb4tYKz9OWja1WRuim82Mt5uzdb5eXVLUnlCCgqt9LjN6yDHPm7UjMwQMG8V0kFPIkL4ZGb/5WfXXa2NJY1Qq3GbFGFQID49vw/XDP6B9q9kRIL4D/NuLUocRUvw5iHZciqygpnJl1GaRcVr%2B5%2BBbKBw3c0Gou4X/ojiewnds2pYPPxNGKploy88l4GcjpGw%2BXmDiP4wUgCojhRporBjp2y87AnaY1k6BSI1j9xHxiSnjXT7pMsyXpBfMYCoAwV/w1Fh1E/Tu1ygXJhaOHAx%2B19BxOIYPWFJVw3djggbkN1jRo%2Bde%2BolGjfEXtFarwfx4nyCeNyYAd0%3D
Vary: Accept-Encoding
URL_REQUEST_DELEGATE [dt=0]
+URL_REQUEST_DELEGATE [dt=3]
DELEGATE_INFO [dt=3]
--> delegate_info = "AsyncResourceHandler"
-URL_REQUEST_DELEGATE
CANCELLED
As I mentioned, if you go back to version 33, it works even though the client
was sending the host name in the Origin header for all requests:
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg?timestamp=1437076851710 HTTP/1.1
Host: media-qa.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1550 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Location: https://qa-app.example.com/oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437076851710
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /oauth/authorize/?request_uri=https%3A//media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ%3D%3D.jpg%3Ftimestamp%3D1437076851710 HTTP/1.1
Host: qa-app.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1763 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-HTTP-Method-Override, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Location: https://media-qa.example.com/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?timestamp=1437076851710&access_token=C30mMVgoZSZtkpm3vgMNfLZEpkKT//%2BiZK5gbR39dvPfIaezfjNMocXJ0UCCH10jcE0yvOIrT8yISHerVvGZlGPy2rr2YwXkh1IsYcl0uNGYOP2bDYyz1cJNAwnRYZ4qS0uctDQiKNGZi3oC10TdIwzhz8aaOFAosRFEjPqrT553aXjpZr2SE4Z73TtU2pd%2B7ILICARbjp0r9yhDAAauJgQHkBAkcLVvW5TARQBeRR1OtXbf0CjN764EZ/2GEqCRhvo0rtVUQGUVpt/Sur9yFYUh1b/rFOZJ0o/Oj8rEUEg2c8p/O1ZrpN8emKMB%2BVWLXG97DPO6QpQmzGvaYCZsUDwGfvPNJ8wCtXEdQF0RzQMv3HG71StD9lK30BB46sDTuP24w7tH4PxqjY0cWBUpaMMz/mKLWuSWY6lerx7ibB7Gp%2B9OsclEHeaxKwFr%2BD63RFPmTwBtHKOF/PjIo%2BbmoxJZ07eJYAEYXDtfoLmFvM8%3D
Vary: Accept-Encoding
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?timestamp=1437076851710&access_token=C30mMVgoZSZtkpm3vgMNfLZEpkKT//%2BiZK5gbR39dvPfIaezfjNMocXJ0UCCH10jcE0yvOIrT8yISHerVvGZlGPy2rr2YwXkh1IsYcl0uNGYOP2bDYyz1cJNAwnRYZ4qS0uctDQiKNGZi3oC10TdIwzhz8aaOFAosRFEjPqrT553aXjpZr2SE4Z73TtU2pd%2B7ILICARbjp0r9yhDAAauJgQHkBAkcLVvW5TARQBeRR1OtXbf0CjN764EZ/2GEqCRhvo0rtVUQGUVpt/Sur9yFYUh1b/rFOZJ0o/Oj8rEUEg2c8p/O1ZrpN8emKMB%2BVWLXG97DPO6QpQmzGvaYCZsUDwGfvPNJ8wCtXEdQF0RzQMv3HG71StD9lK30BB46sDTuP24w7tH4PxqjY0cWBUpaMMz/mKLWuSWY6lerx7ibB7Gp%2B9OsclEHeaxKwFr%2BD63RFPmTwBtHKOF/PjIo%2BbmoxJZ07eJYAEYXDtfoLmFvM8%3D HTTP/1.1
Host: media-qa.example.com
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
Cookie: [1550 bytes were stripped]
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 302 FOUND
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, X-Requested-With
Access-Control-Allow-Origin: https://qa-app.example.com
Location: https://gbbrsh.cloudfront.net/media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?Expires=1437076916&Signature=WBDGSQXer-zAREYgiD1~DA8pUaNUBha4WrUFt-WI5Soh4Z-5ayw35UocOG7DuC9FOnAQAeU5Nvp8hKdofDB--ic4aMH0e~LmHaJ38GtP-lHnyyfQDpjJOEmGM2GY3sB0KG7qa8~eTXX9jKDJTCG9Hkf0EpievuWwiXEKGYaSbe0tkR4CLyhND3sIDJbFGCQQZ7NmhMB-3vOsqDKYKKz9SebuiqO0qbL8SvqBkMEiufXCF2MriR4hVDEjFQssE3ysBbhiMlkaINAeOkEmiZEAjnhB-ncN31Lvy4Lo1LxiyCqKH9QwPOpa6ukK0WrYXWwiTi2VRAaxSjm-xgbGiIArmA__&Key-Pair-Id=APKAJNUAAHKHVOSPPXTQ
HTTP_TRANSACTION_SEND_REQUEST_HEADERS
--> GET /media/uploads/bucket/a746a337-5c20-46a6-a1fc-701e772970fd-bWFpbi1uLW4tMC0wLTAtNDUwLTQ0NQ==.jpg?Expires=1437076916&Signature=WBDGSQXer-zAREYgiD1~DA8pUaNUBha4WrUFt-WI5Soh4Z-5ayw35UocOG7DuC9FOnAQAeU5Nvp8hKdofDB--ic4aMH0e~LmHaJ38GtP-lHnyyfQDpjJOEmGM2GY3sB0KG7qa8~eTXX9jKDJTCG9Hkf0EpievuWwiXEKGYaSbe0tkR4CLyhND3sIDJbFGCQQZ7NmhMB-3vOsqDKYKKz9SebuiqO0qbL8SvqBkMEiufXCF2MriR4hVDEjFQssE3ysBbhiMlkaINAeOkEmiZEAjnhB-ncN31Lvy4Lo1LxiyCqKH9QwPOpa6ukK0WrYXWwiTi2VRAaxSjm-xgbGiIArmA__&Key-Pair-Id=APKAJNUAAHKHVOSPPXTQ HTTP/1.1
Host: gbbrsh.cloudfront.net
Origin: https://qa-app.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Referer: https://qa-app.example.com/media/photos/
HTTP_TRANSACTION_READ_RESPONSE_HEADERS
--> HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://qa-app.example.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin
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:
Client: XHR POST request to /rest
Server: responds with HTTP 302 redirect to /rest/
Client: Follow that redirect
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?
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
Allows 3XX redirect , if the request to the redirected resource doesn't require pre-flight check (simple CORS requests without custom header for example). See https://www.w3.org/TR/cors/#simple-cross-origin-request-0
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
Don't allow 3XX redirect, if the request to redirected resource requires pre-flight check. See https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
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.
http://httpstatus.es/302
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
I also had the problem that Chrome was not following a redirect on a CORS request. For me the problem was that the JS-framework I use (Sencha Touch) adds a request header: X-Requested-With: "XMLHttpRequest"
As soon as I removed this (in Sencha Touch by calling Ext.Ajax.setUseDefaultXhrHeader(false);) it worked like a charm.
Not sure why but I hope this information helps someone.
I'm having an issue where the Places Search API returns ZERO_RESULTS on the m.site whatever the parameter. API Response attached. The search function had been working correctly until January when we began experiencing problems despite no change to the coding. I would appreciate any help. Thanks, Kyle.
GET https://maps.googleapis.com/maps/api/js/PlaceService.FindPlaces?1m6&1m2&1d53.46731217725638&2d-2.2817558287549673&2m2&1d53.46731217725638&2d-2.2817558287549673&2sen-GB&3sphones%204u&6sstore&8e1&callback=_xdc_._7otmgw&token=86621 HTTP/1.1
Host: maps.googleapis.com
Referer: http://m.phones4u.co.uk/stores/my-phones4u-stores/53.46731217725638/-2.2817558287550095/?mweb=640-0-3
Proxy-Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-gb
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_0_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A525 Safari/8536.25
HTTP/1.1 200 OK
Content-Type: text/javascript; charset=UTF-8
Access-Control-Allow-Origin: *
Date: Fri, 25 Jan 2013 11:25:45 GMT
Server: mafe
Cache-Control: private
Content-Length: 115
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
_xdc_._7otmgw && _xdc_._7otmgw( {
"html_attributions" : [],
"results" : [],
"status" : "ZERO_RESULTS"
}
)