自定义请求头引起预检请求
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义请求头引起预检请求相关的知识,希望对你有一定的参考价值。
参考技术AAccess-Control-Allow-Headers 一定不要设置为 * 在移动端会出现 预检请求不通过的状况,切记切记切记!!!
跨域资源共享( CORS ) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器 不同的域、协议或端口 请求一个资源时,资源会发起一个 跨域 HTTP 请求 。
与简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:
使用了下面任一 HTTP 方法:
也就是说 当你自定义了请求头,浏览器就会先发送预检请求,期望得到想要的 Access-Control-Allow-Headers 返回头
下面是一个预检请求,因为我添加了两个自定义请求头: authorization 、 custom
这是服务器给我们的返回头为:
请注意,因为返回头没有 Access-Control-Allow-Headers 所以浏览器阻止了接下来的get请求
正确的返回头:
这里填写的是被允许的自定义请求头
如何在 CORS 预检 OPTIONS 请求中发送自定义标头?
【中文标题】如何在 CORS 预检 OPTIONS 请求中发送自定义标头?【英文标题】:How do you send a custom header in a CORS preflight OPTIONS request? 【发布时间】:2012-12-09 06:59:54 【问题描述】:我正在尝试为 JSON 有效负载发送 CORS 请求。我控制服务器和客户端。
我在这里关注: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control
服务器有一个自定义标头,必须与每个请求一起发送。因此,此自定义标头使请求“不简单”,因此必须使用 OPTIONS 请求对请求进行预检。
我可以看到 jquery 发出 OPTIONS 请求,但它没有发送自定义标头。
我尝试过的方法:
使用 beforeSend 选项:http://api.jquery.com/jQuery.ajax/ 使用 ajax 预过滤器:http://api.jquery.com/jQuery.ajaxPrefilter/在这两种情况下,浏览器都不会发送自定义标头。
我使用的是 FF 17.0.1,jquery 1.8.3。
【问题讨论】:
在您尝试设置标头的位置显示您的代码。 选项headers: Header-name: value
选项不起作用?
导致问题的标题名称是什么?我同意 Barmar 的观点,显示你所有的 JS 代码,请求/响应可以帮助调试。
'冒昧地更新了标题以更准确地反映您所询问的问题。希望没关系。 :)
【参考方案1】:
您的问题不在于 jquery,而在于 how CORS works。您的 beforeSend 回调可能按预期工作......但无论如何浏览器都不会在预检请求中发送自定义标头。这是设计使然;预检请求的目的是确定允许用户代理(浏览器)发送超出 CORS 规范中定义的“简单”内容的信息。因此,对于用户代理发送任何非简单数据(例如您的自定义标头)作为预检请求的一部分是弄巧成拙的。
要指示用户代理在实际的 CORS 请求中包含您的自定义标头,请在您的预检响应中包含 Access-Control-Allow-Headers
header。值得注意的是,如果您不太关心用户代理传输的标头,我相信您可以将Access-Control-Request-Headers
请求标头字段的值作为您在响应中发送的Access-Control-Allow-Headers
的值回显。
您可能还希望包含在syntax section of the spec 中定义的其他一些Access-Control-Allow-*
标头。
另见CORS - How do 'preflight' an httprequest?
另请参阅Mozilla's CORS preflight example,它显示了这些标头的作用。
【讨论】:
谢谢。在预检响应发生后,我的工作正常,这只是 OPTIONS 调用的问题。看来我必须使用基于服务器的解决方法。 @mooreds - 您能否提供在预检请求中发送/接收的标头的快照?您的服务器是否因为没有自定义标头而拒绝 OPTIONS 请求? '猜猜我不明白为什么在预检响应之后一切正常,你仍然需要服务器解决方法。 是的,OPTIONS 请求被拒绝,因为它没有自定义标头。在 chrome 上,其余的数据仍然发送(可能是因为我在 localhost 上开发,不确定),但是对于 Firefox,一旦 OPTIONS 请求失败,其余的请求也会失败。 到目前为止我能想到的一种解决方法是禁用 OPTIONS 请求的自定义标头检查。显然,如果您无法控制服务器,那将是行不通的,所以我很想听听任何其他建议。 (这是一个答案,但已被删除) 您是否找到了不需要(重新)配置服务器(即如果您无权访问它)的解决方案?以上是关于自定义请求头引起预检请求的主要内容,如果未能解决你的问题,请参考以下文章