我无法使用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
错误。
我做错了什么?
答案 0 :(得分:40)
我written an article有一个完整的CORS设置。
我发现了几个可能导致此问题的问题:
Access-Control-Allow-Origin
不能是通配符。最简单的方法是将请求的Origin
标头复制到此字段。完全不清楚标准为什么不允许使用通配符。OPTIONS
请求。为了帮助调试,我添加了标题Access-Control-Max-Age: 1
open
命令的用户名/密码显然不可用作凭据。您必须自己添加Authorization
标题。 xhr.setRequestHeader( 'Authorization', 'Basic ' + btoa( user + ':' + pass ) )
总的来说,withCredentials
系统相当于脑死亡。简单地编写一个接受授权的服务器作为请求主体的一部分会更容易。
答案 1 :(得分:0)
我发现适用于preflight请求的唯一方法是:
ajax
与withCredentials
一起使用:$.ajax({
type: 'POST',
xhrFields: {
withCredentials: true
},
...
});
令人惊讶的是,如果我仅将xhr.withCredentials设置为true
,它将无法正常工作:
$.ajax({
type: 'POST',
beforeSend: function (jqxhr) {
jqxhr.withCredentials = true; // This doesn't work
},
...
});