为什么在铬经过身份验证的CORS请求工作preflight OPTIONS请求,但没有Firefox的? [英] Why does the preflight OPTIONS request of an authenticated CORS request work in Chrome but not Firefox?

查看:159
本文介绍了为什么在铬经过身份验证的CORS请求工作preflight OPTIONS请求,但没有Firefox的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个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规范的C​​ORS preflight请求明确规定,用户凭据应排除在外。有一个在 Chrome浏览器错误和的WebKit 其中选项请求返回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提交与链接到的 W3公开的webapps邮件列表要求的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的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆