请求标头字段在预检响应中不允许使用Access-Control-Allow-Headers

mib*_*bit 204 cors express meanjs

我多次遇到过CORS问题并且通常可以修复它但我希望通过从MEAN堆栈范例中看到这一点来真正理解它.

之前我只是在我的快速服务器中添加中间件来捕获这些东西,但看起来有某种预挂钩错误地提出了我的请求.

请求标头字段Access-Control-Allow-Headers在预检响应中不允许使用Access-Control-Allow-Headers

我以为我可以这样做:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})
Run Code Online (Sandbox Code Playgroud)

或等效但这似乎没有解决它.我当然也试过了

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})
Run Code Online (Sandbox Code Playgroud)

仍然没有运气.

Ann*_*nne 209

当您开始使用自定义请求标头时,您将获得CORS预检.这是一个使用HTTP OPTIONS动词的请求,包括几个标题,其中一个是Access-Control-Request-Headers标题列出了客户端要包含在请求中的标头.

您需要使用适当的CORS标头回复该CORS预检,才能使其正常工作.其中一个确实是Access-Control-Allow-Headers.该标头需要包含标头包含的相同值Access-Control-Request-Headers(或更多).

https://fetch.spec.whatwg.org/#http-cors-protocol更详细地解释了此设置.

  • 如果您使用Chrome并且不确定要求的标头,请使用开发者控制台,网络选择正在进行的呼叫,您可以查看"Access-Control-Request-Headers"正在请求的标头. (36认同)
  • @Demodave对我来说这个例子是`header("Access-Control-Allow-Headers:Content-Type")` (5认同)
  • 请举个例子! (4认同)
  • Developer Console选项很好.您还可以通过访问服务器上的请求对象并转储标头的值来查找所需内容,尤其是"Access-Control-Request-Headers"的标头值.然后,将其复制/粘贴到您的response.setHeader("Access-Control-Allow-Headers","{paste here}")中 (3认同)

小智 98

这是您需要添加以使其工作的内容.

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
Run Code Online (Sandbox Code Playgroud)

浏览器发送预检请求(方法类型为OPTIONS)以检查是否允许从其他域上的浏览器访问服务器上托管的服务.为了响应预检请求,如果你注入上面的标题,浏览器会理解可以进一步调用,我将获得对我的实际GET/POST调用的有效响应.您可以使用Access-Control-Allow-Origin","localhost,xvz.com"而不是*来约束授予访问权限的域.(*将授予对所有域的访问权限)

  • 对于`...- Credentials`,你不能把'*`用于'...- Origin`和'true`.对于非凭证请求,它不会失败,但它也不适用于凭证请求.请参阅我在答案中发布的链接. (6认同)
  • 这是说由于“预检”,服务器端所有这些响应标头都是必要的吗?为什么?特别是对于完美标准的标题?使用 HTTP 一段时间后,需要这么多样板文件对我来说是个新闻。 (2认同)

ngu*_*yên 68

这个问题解决了

 "Origin, X-Requested-With, Content-Type, Accept, Authorization"
Run Code Online (Sandbox Code Playgroud)

特别是在我的项目中(express.js/nodejs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});
Run Code Online (Sandbox Code Playgroud)

更新:

每次出错:Access-Control-Allow-Headers is not allowed by itself in preflight response错误你都可以看到chrome开发者工具有什么问题:
在此输入图像描述

上面的错误是缺少Content-Type这样的字符串添加Content-TypeAccess-Control-Allow-Headers

  • 还要确保您以美国方式而不是英国方式拼写授权。那是我生命中的半小时,我不会回来。谢谢美国![叹] (4认同)
  • 这并不适合所有人。Access-Control-Request-Headers 的值可能会因环境而异。访问服务器上的请求对象并转储“Access-Control-Request-Headers”标头的值。然后,将其复制/粘贴到您的response.setHeader("Access-Control-Allow-Headers", "{paste here}") (2认同)

use*_*456 14

接受的答案还可以,但我很难理解它.所以这里有一个简单的例子来澄清它.

在我的ajax请求中,我有一个标准的Authorization标头.

    $$(document).on('ajaxStart', function(e){
    var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
    if( auth_token ) {
        var xhr = e.detail.xhr;

        xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
    }
Run Code Online (Sandbox Code Playgroud)

此代码在问题中产生错误.我在nodejs服务器上要做的就是在允许的头文件中添加Authorization:

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');
Run Code Online (Sandbox Code Playgroud)


Jan*_*nne 7

只是补充一点,您也可以将这些标头放入 Webpack 配置文件。在我运行 webpack 开发服务器时,我需要它们。

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS,POST,PUT",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    }
},
Run Code Online (Sandbox Code Playgroud)


Luk*_*oon 6

添加到其他答案.我有同样的问题,这是我在我的快速服务器中使用的代码,允许REST调用:

  app.all('*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'URLs to trust of allow');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    if ('OPTIONS' == req.method) {
    res.sendStatus(200);
    } else {
      next();
    }
  });
Run Code Online (Sandbox Code Playgroud)

这段代码基本上是拦截所有请求并添加CORS头,然后继续我的正常路由.当存在OPTIONS请求时,它仅响应CORS头.

编辑:我正在使用此修复程序在同一台机器上的两个单独的nodejs表达服务器.最后我用一个简单的代理服务器解决了这个问题.


Jos*_*egl 5

我自己也遇到过这个问题,在ASP.NET的上下文中确保你的Web.config看起来像这样:

  <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler"/>-->
  <remove name="TRACEVerbHandler" />
  <!--
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
</handlers>

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>
Run Code Online (Sandbox Code Playgroud)

注意Access-Control-Allow-Headers密钥的授权值.我错过了授权值,这个配置解决了我的问题.


小智 5

在 Chrome 中:

预检响应中的 Access-Control-Allow-Headers 不允许请求头字段 X-Requested-With。

对我来说,此错误是由此调用 URL 中的尾随空格触发的。

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}
Run Code Online (Sandbox Code Playgroud)


小智 5

非常好我在一个silex项目上使用它

$app->after(function (Request $request, Response $response) {
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set("Access-Control-Allow-Credentials", "true");
        $response->headers->set("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
        $response->headers->set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    });
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可以回答这个问题,但提供有关如何和/或解决问题的原因的其他背景将提高答案的长期价值. (2认同)

Sai*_*eek 5

当我们为请求创建自定义标头时,就会出现此问题。此请求使用HTTP OPTIONS并包含多个标头。

此请求所需的标头是Access-Control-Request-Headers,它应该是响应标头的一部分,并且应该允许来自所有源的请求。Content-Type有时它也需要在响应头中。所以你的响应头应该是这样的 -

response.header("Access-Control-Allow-Origin", "*"); // allow request from all origin
response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");
Run Code Online (Sandbox Code Playgroud)


小智 5

res.setHeader('Access-Control-Allow-Headers', '*');


Eri*_*ric 5

我收到了 OP 使用 Django、React 和 django-cors-headers lib 指出的错误。要使用此堆栈修复此问题,请执行以下操作:

在 settings.py 中根据官方文档添加以下内容。

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)
Run Code Online (Sandbox Code Playgroud)


小智 5

花了将近一天后,我才发现添加以下两个代码解决了我的问题。

在 Global.asax 中添加这个

protected void Application_BeginRequest()
{
  if (Request.HttpMethod == "OPTIONS")
  {
    Response.StatusCode = (int)System.Net.HttpStatusCode.OK;             
    Response.End();
  }
}
Run Code Online (Sandbox Code Playgroud)

并在网络配置中添加以下内容

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />        
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
  </customHeaders>
</httpProtocol>
Run Code Online (Sandbox Code Playgroud)