HTTP 预检 (OPTIONS) 请求仅在 IE 中失败

Posted

技术标签:

【中文标题】HTTP 预检 (OPTIONS) 请求仅在 IE 中失败【英文标题】:HTTP preflight (OPTIONS) request fails in IE only 【发布时间】:2018-01-29 05:57:24 【问题描述】:

我尝试向我的 REST API 发出 POST 请求。这是代码 sn-p(使用 AngularJS):

        $http(
            method: 'POST',
            url: url,
            data: reqBody,
            headers: 
                'content-type': 'application/json'
            
        )
        .then(function (response) ...)
        .catch(function (error) ...);

根据this article,是因为HTTP头

“内容类型”:“应用程序/json”

浏览器得出结论,它必须发出一个“不简单”的 HTTP 请求,该请求需要与服务器握手(HTTP 选项请求将在实际 HTTP 请求之前发送)。

Chrome 处理请求就像一个魅力,但 IE(在我的例子中是 11 个)失败并显示以下消息

问题是,HTTP 选项响应包含浏览器处理实际 HTTP 请求所需的一切。

【问题讨论】:

POST OPTIONS请求中是否存在标头? @SergiuParaschiv 我真的不知道 IE POST 请求中是否存在标头,因为它永远不会到达那里。但是,我检查了 Chrome POST 标头,它们就位(POST screenshot in Chrome)。 在我的情况下,我使用的是 IE11(Windows 10 家庭版),是的,所有带有 url “long”(不同类型搜索参数的串联)的 OPTIONS 请求都失败了。如果我删除搜索参数(保留 getAll 标准),则 OPTIONS 请求(在 GET 之前)有效。所以这是由于URL的长度?为什么?我该如何解决这个愚蠢的问题?提前致谢。 【参考方案1】:

您可以在 IE 设置中将站点添加到受信任区域,并将“跨域访问数据源”设置为启用(不是提示):

它不仅适用于 IE 9,也适用于 10+。

更多信息:https://www.webdavsystem.com/ajax/programming/cross_origin_requests

【讨论】:

这解决了问题,但我无法告诉我的所有用户将这些更改应用到您的浏览器中:|【参考方案2】:

我找到了所有这些混乱的原因。

API 服务和网站位于同一个域中,但在不同的端口上。具体来说,API 服务位于:

myDomain.com/apiService

网站位于:

myDomain.com:44443/webSite

因此,当网络浏览器从以下位置初始化调用时:

myDomain.com:44443/webSite/page1

到:

myDomain.com/apiService/service1

由于 CORS,Internet Explorer 阻止了呼叫。出于某种原因,Chrome 在这方面没有那么严格,因为它成功地调用了 API。

为了使其在 Internet Explorer 中运行,我将网站移至与 API 相同的端口:

myDomain.com/apiService

myDomain.com/webSite

【讨论】:

以上是关于HTTP 预检 (OPTIONS) 请求仅在 IE 中失败的主要内容,如果未能解决你的问题,请参考以下文章

CORS HEADERS 仅在预检或每个请求中出现

CORS HEADERS 仅在预检或每个请求中出现

IE 11 上 CORS 预检请求的奇怪问题失败

将 Spring Security(双向 SSL)配置为仅对 CORS 预检 OPTIONS 请求进行身份验证

http跨域预检问题

Laravel/React:barryvdh/laravel-cors 处理预检 HTTP OPTIONS 请求