问题描述
我写一个JavaScript客户端将包括对第三方网站(认为Facebook Like按钮)。它需要从需要基本的HTTP认证的API检索信息。简化的设置是这样的:
I am writing a JavaScript client to be included on 3rd party sites (think Facebook Like button). It needs to retrieve information from an API that requires basic HTTP authentication. The simplified setup looks like this:
一个第三方网站包括这个片段在他们的页面:
A 3rd party site includes this snippet on their page:
<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已配置为与相应的头文件作出回应:
The API has been configured to respond with appropriate headers:
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
注意的访问控制 - 允许 - 原产地
设置为原产地
而不是使用通配符,因为我送一个资格的要求( withCredentials
)。
Note that the Access-Control-Allow-Origin
is set to the Origin
instead of using a wildcard because I am sending a credentialed request (withCredentials
).
一切都已经到位,使异步跨域身份验证的请求,和它的伟大工程在Chrome 25在OS X 10.8.2。在开发工具,我可以看到的选项的网络请求
要求 GET
请求之前,响应回来符合市场预期。
Everything is now in place to make an asynchronous cross-domain authenticated request, and it works great in Chrome 25 on OS X 10.8.2. In Dev Tools, I can see the network request for the OPTIONS
request before the GET
request, and the response comes back as expected.
当在Firefox 19的测试,没有任何网络请求出现在萤火虫的API,并且会在控制台此错误: NS_ERROR_DOM_BAD_URI:访问受限制的URI被拒绝
When testing in Firefox 19, no network requests appear in Firebug to the API, and this error is logged in the console: NS_ERROR_DOM_BAD_URI: Access to restricted URI denied
经过一番挖掘,我发现,<一个href="http://stackoverflow.com/questions/11255173/firefox-wont-send-cross-origin-resource-sharing-$p$p-flight">Gecko不允许用户名和密码,根据意见可以直接在跨站点URI 。我认为这是使用可选的用户名和密码PARAMS到的open()
所以我试图使身份验证请求的另一种方法是为Base64 EN $ C C的凭据$并发送Authorization头:
After much digging, I found that Gecko doesn't allow the username and password to be directly in a cross-site URI according to the comments. I assumed this was from using the optional user and password params to open()
so I tried the other method of making authenticated requests which is to Base64 encode the credentials and send in an Authorization header:
// 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未授权
响应选项
要求这导致谷歌搜索一样,为什么这项工作在Chrome和火狐没有!?这时候,我知道自己有麻烦了。
This results in a 401 Unauthorized
response to the OPTIONS
request which lead to Google searches like, "Why does this work in Chrome and not Firefox!?" That's when I knew I was in trouble.
为什么的不的它在Chrome工作,而不是Firefox的?我怎样才能获得选项
发送请求,一致应对?
Why does it work in Chrome and not Firefox? How can I get the OPTIONS
request to send and respond consistently?
推荐答案
为什么确实的它在Chrome和Firefox的不是工作?
Why does it work in Chrome and not Firefox?
借助 W3规范的CORS preflight请求明确规定,用户凭据应排除在外。有一个在 Chrome浏览器错误和的其中选项
请求返回401状态还是发送后续请求。
The W3 spec for CORS preflight requests clearly states that user credentials should be excluded. There is a bug in Chrome and WebKit where OPTIONS
requests returning a status of 401 still send the subsequent request.
火狐有相关的bug提交与链接到的要求的CORS规范进行修改,允许身份验证标头的发在IIS用户的利益选项
请求。基本上,他们都在等待这些服务器被废弃。
Firefox has a related bug filed that ends with a link to the W3 public webapps mailing list asking for the CORS spec to be changed to allow authentication headers to be sent on the OPTIONS
request at the benefit of IIS users. Basically, they are waiting for those servers to be obsoleted.
我怎样才能获得选项
发送请求,一致应对?
How can I get the OPTIONS
request to send and respond consistently?
只需在服务器(API在这个例子中),以选项
无需身份验证请求作出回应。
Simply have the server (API in this example) respond to OPTIONS
requests without requiring authentication.
Kinvey 做得不错扩大在这一点的同时还链接到 Twitter的API 的问题概述catch-共立案这个确切的方案之前,任何浏览器的问题有趣的是几个星期22的问题。
Kinvey did a good job expanding on this while also linking to an issue of the Twitter API outlining the catch-22 problem of this exact scenario interestingly a couple weeks before any of the browser issues were filed.
这篇关于为什么在铬经过身份验证的CORS请求工作preflight OPTIONS请求,但没有Firefox的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!