为什么经过验证的CORS请求的preflight OPTIONS请求在Chrome中工作,而在Firefox中不起作用?
Why does the preflight OPTIONS request of an authenticated CORS request work in Chrome but not Firefox?
我正在写一个JavaScript客户端包含在第三方网站(想想Facebook的喜欢按钮)。它需要从需要基本HTTP身份验证的API中检索信息。简化后的设置如下所示:
第三方网站在他们的页面上包含了这个片段:
<script
async="true"
id="web-dev-widget"
data-public-key="pUbl1c_ap1k3y"
src="http://web.dev/widget.js">
</script>
widget.js调用API:
var el = document.getElementById('web-dev-widget'),
user = 'token',
pass = el.getAttribute('data-public-key'),
url = 'https://api.dev/',
httpRequest = new XMLHttpRequest(),
handler = function() {
if (httpRequest.readyState === 4) {
if (httpRequest.status === 200) {
console.log(httpRequest.responseText);
} else {
console.log('There was a problem with the request.', httpRequest);
}
}
};
httpRequest.open('GET', url, true, user, pass);
httpRequest.onreadystatechange = handler;
httpRequest.withCredentials = true;
httpRequest.send();
API已配置为使用适当的标头进行响应:
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Methods: "GET, OPTIONS"
Header set Access-Control-Allow-Headers: "origin, authorization, accept"
SetEnvIf Origin "http(s)?://(.+?'.[a-z]{3})$" AccessControlAllowOrigin=$0
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
请注意,Access-Control-Allow-Origin
被设置为Origin
而不是使用通配符,因为我正在发送一个有凭据的请求(withCredentials
)。
现在一切都到位,使异步跨域认证请求,它在OS X 10.8.2的Chrome 25上工作得很好。在Dev Tools中,我可以在GET
请求之前看到OPTIONS
请求的网络请求,并且响应按预期返回。
在Firefox 19中测试时,Firebug中没有出现对API的网络请求,并且此错误记录在控制台:NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
经过一番挖掘,我发现根据评论,Gecko不允许用户名和密码直接在跨站点URI中。我假设这是从使用可选的用户和密码参数到open()
,所以我尝试了另一种方法进行身份验证请求,即Base64编码凭证并发送授权头:
// Base64 from http://www.webtoolkit.info/javascript-base64.html
auth = "Basic " + Base64.encode(user + ":" + pass);
...
// after open() and before send()
httpRequest.setRequestHeader('Authorization', auth);
这导致401 Unauthorized
响应OPTIONS
请求,导致谷歌搜索,"为什么这个工作在Chrome而不是Firefox!?"这时我知道我有麻烦了。
为什么在Chrome而不是Firefox中工作?我怎样才能使OPTIONS
请求一致地发送和响应?
为什么在Chrome而不是Firefox中工作?
CORS预飞行请求的W3规范明确指出应排除用户凭据。有一个bug在Chrome和WebKit中,OPTIONS
请求返回401状态仍然发送后续请求。
Firefox有一个相关的错误文件,该文件以W3公共webapps邮件列表的链接结尾,请求更改CORS规范,允许在OPTIONS
请求中发送身份验证头,以使IIS用户受益。基本上,他们在等待这些服务器被淘汰。
如何使OPTIONS
请求一致地发送和响应?
让服务器(本例中的API)响应OPTIONS
请求,而不需要身份验证。
Kinvey对此做了很好的扩展,同时还链接了Twitter API的一个问题,有趣的是,在任何浏览器问题被提交前几周,该问题概述了这个确切场景的第22条问题。
这是一个旧的帖子,但也许这可以帮助人们完成CORS问题。要解决基本的授权问题,您应该避免对服务器中的OPTIONS请求进行授权。这是一个Apache配置示例。只需在你的VirtualHost或Location中添加这样的东西。
<LimitExcept OPTIONS>
AuthType Basic
AuthName <AUTH_NAME>
Require valid-user
AuthUserFile <FILE_PATH>
</LimitExcept>
这对我来说很特别。我正在发送一个名为'SESSIONHASH'的标头。对于Chrome和Opera来说没有问题,但是Firefox也希望这个标题出现在"Access-Control-Allow-Headers"列表中。否则Firefox会抛出CORS错误。
- jQuery Ajax GET请求工作不正常
- 由于响应中不存在“Access Control Allow Origin”标头,跨域请求停止工作
- Javascript:JSON请求仅在第一次工作
- Jquery ajax方法请求体为null,但poster工作正常
- AWS API网关返回400错误请求,但Postman工作正常
- 只需添加一个'允许跨来源请求'到我的节点应用程序工作
- web工作程序中不同的服务器请求行为
- 如何让应用程序帮助程序方法在发送的请求为 JS 格式时工作
- Web 工作线程中的同步 XHR 请求是否仍会锁定浏览器
- 使用jQuery同步Ajax请求;我不能在Adobe Air上工作
- 跨源请求被POST阻止,但浏览器上的req可以正常工作,但设备上不工作
- API请求在使用phonegap调试时不工作,但在模拟器中工作,为什么
- 在处理请求工作时显示“正在处理”
- MVC 模型绑定无法通过 AJAX 请求工作
- 我不能让我的JSON请求工作
- 为什么post请求工作在本地而不是远程?搜索到的Url不同
- Ajax请求工作,但没有输出
- 如何循环大量的URL请求工作
- Ajax请求工作,但没有CSS和JavaScript
- 可以't设法使CORS请求工作