交叉呼叫与 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/plain
和content-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 一起工作,但在飞行前失败的主要内容,如果未能解决你的问题,请参考以下文章
CORS Origin Spring Boot Jhipster - 飞行前失败
JHipster:CORS 在表单登录时失败(实际请求,不是飞行前)