如何使用Credentials,HTTP Authorization(CORS)创建XMLHttpRequest跨域?

edA*_*a-y 23 http xmlhttprequest cors

我无法使用Authorization标头创建跨域请求(使用Firefox测试).我有没有身份验证的请求,但是一旦我设置withCredentials为true,我就无法再从服务器读取响应了.

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

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'
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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

如果我尝试在"打开"命令中添加用户名/密码,我会收到NS_ERROR_DOM_BAD_URI: Access to restricted URI denied错误消息.

我究竟做错了什么?

edA*_*a-y 42

写了一篇文章,其中包含完整的CORS设置.

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

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

整体而言,这个withCredentials系统相当于脑死亡.简单地编写一个接受授权的服务器作为请求主体的一部分更容易.