交叉呼叫与 Post 一起工作,但在飞行前失败

Posted

技术标签:

【中文标题】交叉呼叫与 Post 一起工作,但在飞行前失败【英文标题】:Cross call working with Post but failing with pre-flight 【发布时间】:2016-07-22 01:35:16 【问题描述】:

我必须从我的网站向第三方域/服务器进行网络服务调用。 当我使用 jQuery Ajax by Post 方法和 content-type:text/plain 进行此调用时,它工作正常。

但是当我将其更改为 content-type: text/xml 时,它正在抛出:

对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' 标头出现在请求的 资源。

即使它设置在第三方服务器上以允许访问我们的网站。我们在使用 content-type:text/plain 进行调用时得到了这个标题。

我们还在第三方服务器上添加了以下内容。

Access-Control-Allow-Methods : Get , Post , Options ,PUT

Access-Control-Allow-Headers: Authorization,origin, content-type, accept

请让我知道飞行前请求没有得到“Access-Control-Allow-Origin”响应的原因是什么?

【问题讨论】:

我已将 Soap 服务更改为 Rest 服务,现在 Options 调用具有所有必需的 control-access-* 标头。我不知道 Soap Call 出了什么问题。 【参考方案1】:

content-type:text/plaincontent-type: text/xml 的区别在于:“text/xml”需要“preflight”,而“text/plain”不需要。

来自MDN:

特别是,在以下情况下会预检请求:

它使用 GET、HEAD 或 POST 以外的方法。此外,如果使用 POST 发送 Content-Type 以外的请求数据 application/x-www-form-urlencoded、multipart/form-data 或 text/plain, 例如如果 POST 请求使用 application/xml 或 text/xml,然后预检请求。

可能导致预检请求失败的一些潜在原因:

    服务器未启用CORS。搜索如何为您的服务器技术启用 CORS。 服务器不使用除“text/plain”以外的请求。例如; Spring 有一个consume option,它定义了可接受的内容类型。 您的帖子中有一个“授权”标题。如果您发送带有凭据的请求,您还应该添加 Access-Control-Allow-Credentials: true 标头。再次来自MDN。

【讨论】:

【参考方案2】:

您的脚本适用于 text/plain 的原因是因为它是一个简单的请求。如果您查看this answer,您会发现您的 text/plain 请求符合简单请求的要求。但是,当您将内容类型更改为 text/xml 时,它会将其更改为“非简单”请求。

为了使您的“非简单”请求有效,您需要了解如何提出飞行前请求。 This website 在“处理不那么简单的请求”下解释了如何做到这一点。

更新

请注意: Access-Control-Allow-Methods 是强制转换敏感的(全部大写),您不需要列出用于简单请求(GET、HEAD、POST)的任何方法。 - source

Access-Control-Allow-Methods: OPTIONS, PUT
Access-Control-Allow-Headers: Authorization, Origin, Content-Type, Accept

Firefox 在同源请求中不包含 Origin 标头。但是 Chrome 和 Safari 在同源 POST/PUT/DELETE 请求中包含 Origin 标头(同源 GET 请求将没有 Origin 标头)。

有没有可能起源相同?

您的caching 可能有问题吗?

确保您有这些 settings 用于您的 jquery ajax 调用:

crossDomain: true // Will force a cross domain request
cache: false

【讨论】:

是的,我知道这是简单的请求,而另一个是“不那么简单的请求”。问题是,在一个请求中,我得到了所有的 access-control-* 标头,但在选项中我没有得到这些标头。所以我的“不那么简单的请求”失败了。

以上是关于交叉呼叫与 Post 一起工作,但在飞行前失败的主要内容,如果未能解决你的问题,请参考以下文章

AWS API Gateway CORS 飞行前检查失败

CORS Origin Spring Boot Jhipster - 飞行前失败

JHipster:CORS 在表单登录时失败(实际请求,不是飞行前)

Angular $http 未在 OPTIONS 飞行前发送标头

未触发 CORS 检查的飞行前请求

为啥这个简单的 CORS 请求会进行飞行前选项检查