CORS:GET 上没有 pre-flight,但 POST 上有 pre-flight
CORS: No pre-flight on GET but a pre-flight on POST
我正在尝试删除我的应用程序中不必要的 pre-flight 请求。为此,我简化了请求的某些部分,删除了自定义 headers 等。但遇到了一个问题 - GET 请求现在可以在没有 pre-flights 的情况下正常工作,但是 POST 请求仍然有它们.
我已经满足了要求:
- 请求未设置自定义 HTTP headers。
- 内容类型是"text/plain; charset=utf-8"。
- 请求方法必须是 GET、HEAD 或 POST 之一。如果 POST,内容类型应为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain.
之一
GET 和 POST 请求都通过单个 httpinvoke 调用。
举个例子 - 没有以 pre-flight:
开头的 GET 请求
URL: http://mydomain/APIEndpoint/GETRequest?Id=346089&Token=f5h345
Request Method:GET
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Type:text/plain; charset=utf-8
Host: correct host
Origin:http://localhost
Pragma:no-cache
Referer: correct referer
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters:
Id=346089
Token=f5h345
还有一个看起来非常相似但仍然以 pre-flight:
开头的 POST 请求
URL: http://mydomain/APIEndpoint/GETRequest?param=TEST
Request Method:POST
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:11
Content-Type:text/plain; charset=UTF-8
Host:
Origin:http://localhost
Pragma:no-cache
Referer:
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters:
param:TEST
Request Payload
{MyData: {}}
如有任何建议,我们将不胜感激!谢谢!
====更新===
根据要求,为 POST 请求发布 pre-flight 请求:
URL: http://mydomain/APIEndpoint/GETRequest?param=TEST
Request Method:OPTIONS
Status Code:200 OK
Response Header
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:0
Date:Wed, 09 Aug 2017 08:02:16 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:correct host
Origin:http://localhost
Pragma:no-cache
Referer: correct referer
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters
param:TEST
这是使用 httpinvoke 库的遗留代码。实际调用的代码片段:
_converters: {
'text json': function (input, reviver) {},
'json text': JSON.stringify
};
headers = {
'Content-Type': 'text/plain; charset=utf-8'
};
data = {params: "test"};
httpinvoke(url, method.toUpperCase(), {
corsExposedHeaders: ['Content-Type'],
headers: headers,
input: data,
converters: _converters,
inputType: 'json',
outputType: 'json',
timeout: self._getMessageTimeout()
}).then(function (res) {}, function (error) {});
如果在 XMLHttpRequestUpload 对象上注册了事件侦听器(强制预检;请参阅 the note on the use-CORS-preflight flag in https://xhr.spec.whatwg.org/, and a related note in https://fetch.spec.whatwg.org/ and the updated documentation on CORS preflight requests in the MDN CORS article),则可能会发生这种情况。
httpinvoke 会这样做吗?
正如@Anne 提到的,尽管请求本身符合 "simple requests" 的规则(因此不需要飞行前),但 POST 仍在发送飞行前请求的原因在于XMLHttpRequestUpload 事件侦听器。
XMLHttpRequestUpload 本身可能不会在代码中提及,但您总能在 xhr.upload 变量中找到它。 http-invoke 库就是这种情况。
看起来完全无辜的代码如下:
xhr.upload.onprogress = onuploadprogress;
实际上会导致强制飞行前请求。
感谢所有帮助解决这个问题的人。
我正在尝试删除我的应用程序中不必要的 pre-flight 请求。为此,我简化了请求的某些部分,删除了自定义 headers 等。但遇到了一个问题 - GET 请求现在可以在没有 pre-flights 的情况下正常工作,但是 POST 请求仍然有它们.
我已经满足了要求:
- 请求未设置自定义 HTTP headers。
- 内容类型是"text/plain; charset=utf-8"。
- 请求方法必须是 GET、HEAD 或 POST 之一。如果 POST,内容类型应为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain. 之一
GET 和 POST 请求都通过单个 httpinvoke 调用。
举个例子 - 没有以 pre-flight:
开头的 GET 请求URL:
http://mydomain/APIEndpoint/GETRequest?Id=346089&Token=f5h345
Request Method:GET
Request Headers:
Accept:
*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Type:text/plain; charset=utf-8
Host: correct host
Origin:
http://localhost
Pragma:no-cache
Referer: correct referer
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters:
Id=346089
Token=f5h345
还有一个看起来非常相似但仍然以 pre-flight:
开头的 POST 请求URL:
http://mydomain/APIEndpoint/GETRequest?param=TEST
Request Method:POST
Request Headers:
Accept:
*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Content-Length:11
Content-Type:text/plain; charset=UTF-8
Host:
Origin:
http://localhost
Pragma:no-cache
Referer: User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters:
param:TEST
Request Payload
{MyData: {}}
如有任何建议,我们将不胜感激!谢谢!
====更新===
根据要求,为 POST 请求发布 pre-flight 请求:
URL:
http://mydomain/APIEndpoint/GETRequest?param=TEST
Request Method:OPTIONS
Status Code:200 OK
Response Header
Access-Control-Allow-Origin:
*
Cache-Control:no-cache
Content-Length:0
Date:Wed, 09 Aug 2017 08:02:16 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Request Headers
Accept:
*/*
Accept-Encoding:gzip, deflate
Accept-Language:uk-UA,uk;q=0.8,ru;q=0.6,en-US;q=0.4,en;q=0.2
Access-Control-Request-Method:POST
Cache-Control:no-cache
Connection:keep-alive
Host:correct host
Origin:
http://localhost
Pragma:no-cache
Referer: correct referer
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
Query String Parameters
param:TEST
这是使用 httpinvoke 库的遗留代码。实际调用的代码片段:
_converters: {
'text json': function (input, reviver) {},
'json text': JSON.stringify
};
headers = {
'Content-Type': 'text/plain; charset=utf-8'
};
data = {params: "test"};
httpinvoke(url, method.toUpperCase(), {
corsExposedHeaders: ['Content-Type'],
headers: headers,
input: data,
converters: _converters,
inputType: 'json',
outputType: 'json',
timeout: self._getMessageTimeout()
}).then(function (res) {}, function (error) {});
如果在 XMLHttpRequestUpload 对象上注册了事件侦听器(强制预检;请参阅 the note on the use-CORS-preflight flag in https://xhr.spec.whatwg.org/, and a related note in https://fetch.spec.whatwg.org/ and the updated documentation on CORS preflight requests in the MDN CORS article),则可能会发生这种情况。
httpinvoke 会这样做吗?
正如@Anne 提到的,尽管请求本身符合 "simple requests" 的规则(因此不需要飞行前),但 POST 仍在发送飞行前请求的原因在于XMLHttpRequestUpload 事件侦听器。
XMLHttpRequestUpload 本身可能不会在代码中提及,但您总能在 xhr.upload 变量中找到它。 http-invoke 库就是这种情况。
看起来完全无辜的代码如下:
xhr.upload.onprogress = onuploadprogress;
实际上会导致强制飞行前请求。
感谢所有帮助解决这个问题的人。