Jquery 为什么我的Drupal 8 CORS设置不起作用?

Jquery 为什么我的Drupal 8 CORS设置不起作用?,jquery,ajax,drupal,cors,drupal-8,Jquery,Ajax,Drupal,Cors,Drupal 8,自从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-

自从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(?)

您需要将服务器后端配置为不需要对
选项
请求进行授权

401响应表示服务器需要对
OPTIONS
请求进行授权,但授权失败,因为请求不包含所需的凭据

原因是,
OPTIONS
请求由浏览器作为CORS的一部分自动发送

一般解释了浏览器发出CORS飞行前
选项
请求的原因,但在问题中的特定情况下,原因是请求包含
授权
请求头

所以现在发生的是:

  • 您的代码告诉您的浏览器它希望发送带有
    授权
    标题的请求
  • 您的浏览器显示,好的,带有
    授权
    标题的请求需要我执行CORS飞行前
    选项
    ,以确保服务器允许带有
    授权
    标题的请求
  • 浏览器将
    选项
    请求发送到服务器,而无需
    授权
    标题
    ,因为
    选项
    检查的全部目的是查看是否可以包含该标题
  • 您的服务器会看到
    选项
    请求,但不会以表示允许请求中的
    授权
    头的方式响应请求,而是使用401拒绝请求,因为它缺少头
  • 您的浏览器预期CORS飞行前会有200或204个响应,但会得到401个响应。因此,您的浏览器就停在那里,从不尝试从代码中获取请求
  • 因此,您需要找出当前服务器端代码的哪一部分导致您的服务器需要对
    选项
    请求进行授权,您需要对此进行更改,以便它在不需要授权的情况下处理
    选项
    请求


    一旦您解决了这个问题,问题中显示的现有
    cors.config
    应该会导致服务器使用包含
    授权的
    访问控制允许标头
    响应标头以正确的方式响应
    选项
    请求,这样您的浏览器就可以说,OK,此服务器允许包含
    授权
    标题的跨源请求,因此我现在将继续发送实际的
    获取
    请求。

    此外,还将发送到正在工作的CORS配置和htaccess设置:

    SetEnvIfNoCase Request_Method OPTIONS noauth
    Order Deny,Allow
    Deny from all
    Require valid-user
    Allow from env=noauth
    Satisfy Any
    
    你必须确保你的ajax设置没有像我的问题中那样的
    带凭证
    密码
    用户名
    。这至少会导致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'
    });
    

    您确定Firefox中出现的问题不仅仅是因为它加载了在服务器端添加CORS配置之前缓存的文档的缓存副本吗?您是否尝试过在Firefox中清除浏览器缓存?为了弄清楚为什么您会看到请求方法是OPTIONS:这是因为请求中存在授权请求头会触发您的浏览器在尝试获取您的请求之前自动发出CORS飞行前选项请求代码正在尝试发送。请求在失眠中起作用的原因是,失眠的跨源请求能力没有受到任何限制,相反,浏览器会阻止前端JavaScript代码访问来自跨源请求的响应,除非这些响应包括access Control Allow origin响应头和任何其他必要的CORS响应头。有详细信息吗?我一个字也不懂:D@sideshowbarker是的,我清除了缓存并设置为禁用网络缓存,使用开发工具在firefox中打开,我的5个ajax json请求中的一个在特定的
    $.ajax()
    调用(或对象)中无法工作,另外还有
    ajaxSetup
    中带有凭据的
    用户名
    密码
    值对存在。chrome和safari显然忽略了这些,而firefox则不会。我向上帝发誓,这正是我所尝试的。我还添加了
    SetEnvIfNoCase请求\u允许的方法选项
    ,但它一开始就不起作用。不过,还是要谢谢你的精彩总结!我在firefox中仍然有问题。在网络选项卡中,我看到响应实际上返回了有效的json,但在jQuery中,它给了我一个错误,即它进入
    fail
    函数,而不是
    done
    函数。
    statusText
    是错误的,没有任何进一步的
    responseText
    如果Firefox没有看到正确的CORS响应,那么您仍然可以在devtools网络选项卡中看到响应。但是,仅仅因为您可以在那里看到它,并不意味着Firefox将允许您的代码访问响应。Firefox只会让你得到响应,如果它看到访问控制允许响应中的源,正确的值。无论如何,为了进一步隔离这个问题,你可以考虑的是用FETCH(…)方法直接写请求代码,而不是jQuery $ Ajax。我自己也不太熟悉variou的效果