自Drupal 8.2以来,cors的设置就是核心。在我的services.yml
(和default.services.yml
)中,我有以下设置:
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['*']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: false
# Sets the Access-Control-Max-Age header.
maxAge: 1000
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: true
我的域a.com
受密码保护。
在域b.com
上,我尝试从域a.com
加载一些API:
$.ajaxSetup({
xhrField: {
withCredentials : true
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic Z2VuaXVzOmNvYXRpbmdz');
}
});
request = $.ajax({
url: apiBaseUrl + 'api/foobar',
dataType: 'json',
type: 'get',
password: 'foo',
username: 'bar'
});
在Chrome中它工作正常,在Firefox中我收到错误。请求标头:
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
响应是401“需要授权”,它说请求方法是OPTIONS(?)。
这里有什么问题?
在insomnia中执行相同的请求完全正常。
答案 0 :(得分:2)
响应是401“需要授权”,它说请求方法是OPTIONS(?)。
您需要将服务器后端配置为不需要OPTIONS
请求的授权。
401响应表明服务器需要授权OPTIONS
请求,但授权失败,因为请求不包含所需的凭据。
原因是,OPTIONS
请求由您的浏览器自动发送,作为CORS的一部分。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests一般解释为什么浏览器会进行CORS预检OPTIONS
请求,但在问题的具体情况下,原因是请求包含Authorization
请求标头。
所发生的事情是:
Authorization
标题发送请求。Authorization
标头的请求要求我执行CORS预检OPTIONS
,以确保服务器允许使用Authorization
标头的请求。OPTIONS
请求发送到服务器而没有Authorization
标题,因为OPTIONS
检查的全部目的是查看是否可以包括那个标题。OPTIONS
请求,但不会以指示它允许请求中的Authorization
标头的方式对其进行响应,而是由于缺少标头而拒绝它,因为它没有标头。GET
请求。因此,您需要弄清楚当前服务器端代码的哪一部分导致您的服务器需要OPTIONS
个请求的授权,并且您需要对其进行更改,以便它改为处理OPTIONS
个请求未经授权不得。
解决问题后,问题中显示的现有cors.config
应该会导致服务器以正确的方式响应OPTIONS
请求 - Access-Control-Allow-Headers
响应标头包含{ {1}},以便您的浏览器可以说,好的,此服务器允许包含Authorization
标头的跨源请求,因此我现在继续发送实际的Authorization
请求。
答案 1 :(得分:1)
除了正常工作的CORS配置和htaccess设置:
SetEnvIfNoCase Request_Method OPTIONS noauth
Order Deny,Allow
Deny from all
Require valid-user
Allow from env=noauth
Satisfy Any
您必须确保您的ajax设置没有withCredentials
以及password
和username
,就像在我的问题中一样。至少这会导致Firefox出错。工作ajax:
$.ajaxSetup({
xhrField: {
withCredentials : true
},
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', 'Basic foobarbarfoo');
}
});
request = $.ajax({
url: isApiActive ? apiBaseUrl + 'api/mydata' : './mydata.json',
dataType: 'json',
type: 'get'
});