CORS request fails in Chrome only if has headers

2020-05-20 09:18发布

问题:

I'm trying to send simple CORS request to external application server which uses session key for authorization.

$.ajax({
    type: "GET",
    url: "https://192.168.1.72:8442/api/file/",
    headers: {"Authorization": "3238562439e44fcab4036a24a1e6b0fb"}
});

It works fine in Firefox 18, Opera 12.12 and Rekonq 2.0 (uses also WebKit) but doesn't work in Google Chrome (tried versions 21 and 24). In Google Chrome it shows OPTIONS Resource failed to load in Network Inspector and application server doesn't get any request. I've tried jQuery 1.8.3 and 1.9.0.

Request URL:https://192.168.1.72:8442/api/file/
Request Headers
Access-Control-Request-Headers:accept, authorization, origin
Access-Control-Request-Method:GET
Cache-Control:no-cache
Origin:https://192.168.1.72:8480
Pragma:no-cache

If I remove headers from the request then I receive 401 also in Google Chrome and it's able to access the resource in case of authorization is disabled on application server. It doesn't matter which headers are sent. Only header I'm able to send is {"Content-Type": "plain/text"}. All other header names/values give an error in Google Chrome but work in all browsers I mentioned above.

Why Google Chrome doesn't handle headers in CORS request?

回答1:

It's a bug in Google Chrome: http://code.google.com/p/chromium/issues/detail?id=96007.



回答2:

I found that Access-Control-Allow-Headers: * should be set ONLY for "OPTIONS" request. If you return it for POST request then browser cancel the request (at least for chrome)

The following PHP code works for me

// Allow CORS
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');    
header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  header("Access-Control-Allow-Headers: *");
}

I found similar questions with some misleading response: - Server thread says that this is 2 years bug of chrome: Access-Control-Allow-Headers does not match with localhost. It's wrong: I can use CORS to my local server with Post normally - Access-Control-Allow-Headers does accept wildcards. It's also wrong, wildcard works for me (I tested only with Chrome)

This take me half day to figure out the issue.

Happy coding



回答3:

I'm using self-signed certificate on my api server and that seems to be the issue. I found that if I start Google Chrome with --disable-web-security option, then CORS with request headers is working. Without --disable-web-security I can send CORS requests to self-signed api server but can't add any headers (except Content-Type).



回答4:

Server side: The server should set the header "Access-Control-Allow-Credentials" and also set the allowed headers in "Access-Control-Allow-Headers".

Client side: You can set xhrFields in $.ajax() instead of explicitly passing Auth header.

xhrFields: {
    withCredentials: true 
}

More details here.