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 请求仍然有它们.

我已经满足了要求:

  1. 请求未设置自定义 HTTP headers。
  2. 内容类型是"text/plain; charset=utf-8"。
  3. 请求方法必须是 GET、HEAD 或 POST 之一。如果 POST,内容类型应为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain.
  4. 之一

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;

实际上会导致强制飞行前请求。

感谢所有帮助解决这个问题的人。