为什么我的Drupal 8 CORS设置不起作用?
从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
是受密码保护的htaccess。
在域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(?)。
这有什么不对吗?
在失眠中做同样的要求完全没问题。
响应是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
标头的请求。 - 您的浏览器在没有
Authorization
标头的情况下将OPTIONS
请求发送到服务器,因为OPTIONS
检查的全部目的是查看是否可以包含该标头。 - 您的服务器看到
OPTIONS
请求,但不是以指示它允许请求中的Authorization
标头的方式响应它,而是因为它缺少标头而拒绝它使用401。 - 您的浏览器需要200或204的CORS预检响应,而是获得401响应。 因此,您的浏览器就在那里停止,从不尝试从您的代码中
GET
请求。
因此,您需要弄清楚当前服务器端代码的哪个部分导致您的服务器需要OPTIONS
请求的授权,并且您需要更改它以便在不需要授权的情况下处理OPTIONS
请求。
解决之后,问题中显示的现有cors.config
应该使服务器以正确的方式响应OPTIONS
请求 – 使用包含Authorization
的Access-Control-Allow-Headers
响应头,以便您的浏览器可以说,好吧,这个服务器允许包含Authorization
标头的跨源请求,所以我现在继续发送实际的GET
请求。
除了工作的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' });
- 使用AJAX将PDF文件发送到服务器(PHP LARAVEL)
- 如何使用Django,Ajax,jQuery提交表单而不刷新页面?
- 如何用ajax响应替换整个html网页?
- applyBindings()太快,在Ajax请求完成之前调用
- JQuery Ajax POST在没有发出请求的情况下抛出一个空错误
- 可以使用xhrFields将onprogressfunction添加到jQuery.ajax()吗?
- Ajax调用从RESTful服务返回的下载文件
- Ajax jquery调用获取NetworkError:403 Forbidden错误响应
- 在Webservice ajax调用中的Modal Popup Extender中显示加载图像