【问题标题】:How to make XMLHttpRequest cross-domain withCredentials, HTTP Authorization (CORS)?如何使用凭据、HTTP 授权 (CORS) 使 XMLHttpRequest 跨域?
【发布时间】:2014-03-18 00:15:23
【问题描述】:

我无法使用 Authorization 标头发出跨域请求(使用 Firefox 进行测试)。我的请求无需身份验证即可工作,但一旦我将 withCredentials 设置为 true,我就无法再读取来自服务器的响应。

在服务器上,我发回这些标头(使用 Flask 中的 after_request 方法):

resp.headers['Access-Control-Allow-Origin'] = '*'
resp.headers['Access-Control-Allow-Credentials'] = 'true'
resp.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
resp.headers['Access-Control-Allow-Headers'] = 'Authorization'

Firefox 从未实际调用过任何 OPTIONS。在客户端我进行 XMLHttpRequest 调用:

var xhr = new XMLHttpRequest()
xhr.open( 'POST', 'http://test.local:8002/test/upload', true)
xhr.withCredentials = true
xhr.onreadystatechange = function() {
    console.log( xhr.status, xhr.statusText )
}
xhr.send(fd)

如果没有withCredentials 设置,日志语句会将预期信息记录到控制台。一旦我设置了值,但是 xhr 不允许访问,我只写一个 0 值和一个空字符串。我这里没有设置授权标头,但这应该不会影响我读取结果的能力。

如果我尝试将用户名/密码添加到“打开”命令,我会收到 NS_ERROR_DOM_BAD_URI: Access to restricted URI denied 错误。

我做错了什么?

【问题讨论】:

    标签: http xmlhttprequest cors


    【解决方案1】:

    我发现与preflight 请求一起使用的唯一方法是:

    • 通过将身份验证逻辑移动到代码(例如从 Apache 到 PHP)来禁用 OPTIONS 方法请求的身份验证。
    • 使用 jQuery ajax 调用 withCredentials:
    $.ajax({
        type: 'POST',
        xhrFields: {
            withCredentials: true
        },
        ...
    });
    

    令人惊讶的是,如果我只是将 xhr.withCredentials 设置为 true 它不起作用:

    $.ajax({
        type: 'POST',
        beforeSend: function (jqxhr) {
            jqxhr.withCredentials = true; // This doesn't work
        },
        ...
    });
    

    【讨论】:

      【解决方案2】:

      我已经 written an article 完成了 CORS 设置。

      我发现了几个可能导致此问题的问题:

      1. 如果使用凭据,Access-Control-Allow-Origin 不能是通配符。最简单的方法是将请求的Origin 标头复制到此字段。完全不清楚为什么该标准不允许使用通配符。
      2. 即使您清除缓存(可能是会话),Firefox 也会缓存访问控制结果。重新启动迫使它执行一个新的OPTIONS 请求。为了帮助调试,我添加了标题Access-Control-Max-Age: 1
      3. open 命令的用户名/密码显然不能用作凭据。您必须自己添加 Authorization 标头。 xhr.setRequestHeader( 'Authorization', 'Basic ' + btoa( user + ':' + pass ) )

      总体而言,withCredentials 系统相当脑残。简单地编写一个接受授权作为请求正文的一部分的服务器会更容易。

      【讨论】:

      • 非常感谢!过去一周,我一直在为 CORS 和用户授权而苦苦挣扎。阅读您的答案后,我决定自己进行用户授权。奇迹般有效。是的,“脑死亡”是一个非常贴切的描述。
      猜你喜欢
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 2016-12-26
      • 2014-03-27
      • 1970-01-01
      • 2014-03-10
      • 2011-01-04
      相关资源
      最近更新 更多