当前位置: 首页 > 面试题库 >

为什么经过身份验证的CORS请求的预检OPTIONS请求在Chrome中有效,但在Firefox中不起作用?

爱繁
2023-03-14
问题内容

我正在编写一个JavaScript客户端,该客户端将包含在第3方网站上(想像Facebook
Like按钮)。它需要从需要基本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中运行良好。在开发工具中,我可以在OPTIONS请求之前看到请求的网络GET请求,并且响应将按预期返回。

在Firefox 19中进行测试时,Firebug中没有向API发出网络请求,并且此错误记录在控制台中: NS_ERROR_DOM_BAD_URI: Access to restricted URI denied

经过大量挖掘,我发现Gecko不允许用户名和密码根据评论直接在跨站点URI中。我以为这是从使用可选的用户和密码参数开始的,open()所以我尝试了另一种进行身份验证的请求的方法,即对Base64编码凭据并发送Authorization标头:

// 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 UnauthorizedOPTIONS请求的响应导致了Google搜索,例如“为什么这在Chrome而不是Firefox中有效!”。那是我知道自己遇到麻烦的时候。

为什么 没有 它在Chrome和Firefox的不是工作?如何获得OPTIONS一致发送和响应的请求?


问题答案:

为什么 没有 它在Chrome和Firefox的不是工作?

针对CORS预检请求的[W3规范明确指出应排除用户凭据。Chrome和WebKit中存在一个错误,其中OPTIONS返回状态401的请求仍会发送后续请求。

Firefox有一个相关的错误文件,该错误的结尾是一个指向W3公共Web应用程序邮件列表的链接,该链接要求更改CORS规范,以允许OPTIONS对IIS用户有利的请求发送身份验证标头。基本上,他们正在等待这些服务器被淘汰。

如何获得OPTIONS一致发送和响应的请求?

只需让服务器(在此示例中为API)响应OPTIONS请求即可,而无需身份验证。

Kinvey在扩展此功能方面做得很好,同时还与TwitterAPI的问题进行了链接,概述了这种确切情况的catch22问题,有趣的是,在提出任何浏览器问题之前几周。



 类似资料:
  • 经过身份验证的请求可用于获取授权代码令牌,以访问系统中的所有者资源。 对授权端点发出的请求会导致用户身份验证,并在向授权端点发送请求时提供明确的凭据。 经过身份验证的请求包含以下参数 - response_type - 这是一个必需参数,用于将值设置为'code',用于请求授权代码。 如果授权请求中没有'response_ type'参数,则授权服务器返回错误响应。 由于无效或不匹配的重定向URI

  • 我正在使用凭据和预检请求实现CORS,我有点困惑为什么预检请求在Firefox 30中始终失败,但在Safari(7.0.2)和Chrome35中有效。我认为这个问题不同于“为什么经过身份验证的CORS请求的预检OPTIONS请求在Chrome而不是Firefox中有效?”因为我没有收到401,而是来自浏览器客户端的特定CORS消息: “跨源请求已阻止:同源策略不允许读取 http://myurl

  • 问题内容: 我正在尝试将API查询输入python。命令行 提供一些json输出。myToken是一个十六进制变量,始终保持不变。我想从python进行此调用,以便我可以遍历不同的id并分析输出。有任何想法吗?在需要身份验证之前,我已经使用urllib2进行了此操作。我也查看了请求模块,但无法弄清楚该怎么做。 非常感谢。 问题答案: 该请求包有一个用于HTTP请求的一个非常好的API,加入了自定义

  • 我第一次尝试使用Google Firestore,通过Google api身份验证进行身份验证。我要做的第一件事是用几个方法来填充数据库,当我等待批处理任务时,会出现以下错误: 我几乎找不到谷歌认证连接firestore的方法。首先,我使用google console为我的应用程序提供的密码使用此方法进行身份验证: 使用在我的google控制台中为应用程序配置的相同作用域(我在同一应用程序中使用g

  • 问题内容: 在我的应用中,我正在创建从HTTP到HTTPS的AJAX请求。这意味着我需要CORS。因此,我向jQuery.ajax添加了一些标题和参数并对其进行了测试。在Firefox中,一切正常,但在Chrome中,一切正常。Chrome会“杀死”每一个预先提出的请求(选项)。 jQuery脚本: HTTP转储: 有人知道为什么Chrome会终止此请求吗? 问题答案: 也许您的https服务器具

  • 我得到了一个使用fcm发送通知的应用程序,当我通过控制台发送消息时一切正常,但是当我尝试通过php(curl-post)或postman(firefox扩展)发送消息时,我得到了一个身份验证错误(甚至使用了密钥) 字符串(304)“{”错误:{”代码:401,“消息”:“请求缺少所需的身份验证凭据。应为OAuth 2访问令牌、登录cookie或其他有效身份验证凭据。请参阅https://devel