CORS Access-Control-Allow-Headers 通配符被忽略?

Posted

技术标签:

【中文标题】CORS Access-Control-Allow-Headers 通配符被忽略?【英文标题】:CORS Access-Control-Allow-Headers wildcard being ignored? 【发布时间】:2012-10-20 06:12:37 【问题描述】:

我无法让跨域 CORS 请求使用 Chrome 正常工作。

请求标头:

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (Khtml, like Gecko) Chrome/22.0.1229.94 Safari/537.4

响应标头:

Access-Control-Allow-Headers:*
Access-Control-Allow-Origin:*
Allow:GET, POST, OPTIONS
Content-Length:0
Date:Tue, 30 Oct 2012 20:04:28 GMT
Server:BaseHTTP/0.3 Python/2.7.3

错误:

XMLHttpRequest cannot load domain. Request header field Content-Type is not allowed by Access-Control-Allow-Headers.

提供选项请求的python代码是:

self.send_response(200)
self.send_header('Allow', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Headers', '*')
self.send_header('Content-Length', '0')
self.end_headers()

Access-Control-Allow-Origin 通配符似乎被忽略了?

【问题讨论】:

【参考方案1】:

仅在 2016 年 5 月才支持 Access-Control-Allow-Headers 标头中的通配符 added to the living standard,因此可能并非所有浏览器都支持。在尚未实现此功能的浏览器上,它必须完全匹配:https://www.w3.org/TR/2014/REC-cors-20140116/#access-control-allow-headers-response-header

如果您希望有大量的标头,您可以读入 Access-Control-Request-Headers 标头的值并将该值回显到 Access-Control-Allow-Headers 标头中。

【讨论】:

resp.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers")); // 允许任何标题 在 ruby​​ 上,“如果 request.headers['Access-Control-Request-Headers'] 那么 headers['Access-Control-Allow-Headers'] = request.headers['Access-Control- Request-Headers'] end" 对我来说看起来不错。 @monsur:this answer 指出现在允许使用通配符,至少在理论上是这样,所以我更新了你的答案以反映这一点。如果您不喜欢我的风格,请随时根据您的喜好进行编辑。 一句警告,如果您还允许浏览器缓存预检响应(使用 Access-Control-Max -年龄)。你不知道第一个请求列出了所有连续请求的header。 @monokrome 如果您能告诉我们这将如何成为生产中的安全问题,那就太好了..【参考方案2】:

那些 CORS 标头不支持将 * 作为值,唯一的方法是将 * 替换为:

Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With


.htaccess 示例(包括 CORS):

<IfModule mod_headers.c>
  Header unset Connection
  Header unset Time-Zone
  Header unset Keep-Alive
  Header unset Access-Control-Allow-Origin
  Header unset Access-Control-Allow-Headers
  Header unset Access-Control-Expose-Headers
  Header unset Access-Control-Allow-Methods
  Header unset Access-Control-Allow-Credentials

  Header set   Connection                         keep-alive
  Header set   Time-Zone                          "Asia/Jerusalem"
  Header set   Keep-Alive                         timeout=100,max=500
  Header set   Access-Control-Allow-Origin        "*"
  Header set   Access-Control-Allow-Headers       "Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With"
  Header set   Access-Control-Expose-Headers      "Accept, Accept-CH, Accept-Charset, Accept-Datetime, Accept-Encoding, Accept-Ext, Accept-Features, Accept-Language, Accept-Params, Accept-Ranges, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Expose-Headers, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Age, Allow, Alternates, Authentication-Info, Authorization, C-Ext, C-Man, C-Opt, C-PEP, C-PEP-Info, CONNECT, Cache-Control, Compliance, Connection, Content-Base, Content-Disposition, Content-Encoding, Content-ID, Content-Language, Content-Length, Content-Location, Content-MD5, Content-Range, Content-Script-Type, Content-Security-Policy, Content-Style-Type, Content-Transfer-Encoding, Content-Type, Content-Version, Cookie, Cost, DAV, DELETE, DNT, DPR, Date, Default-Style, Delta-Base, Depth, Derived-From, Destination, Differential-ID, Digest, ETag, Expect, Expires, Ext, From, GET, GetProfile, HEAD, HTTP-date, Host, IM, If, If-Match, If-Modified-Since, If-None-Match, If-Range, If-Unmodified-Since, Keep-Alive, Label, Last-Event-ID, Last-Modified, Link, Location, Lock-Token, MIME-Version, Man, Max-Forwards, Media-Range, Message-ID, Meter, Negotiate, Non-Compliance, OPTION, OPTIONS, OWS, Opt, Optional, Ordering-Type, Origin, Overwrite, P3P, PEP, PICS-Label, POST, PUT, Pep-Info, Permanent, Position, Pragma, ProfileObject, Protocol, Protocol-Query, Protocol-Request, Proxy-Authenticate, Proxy-Authentication-Info, Proxy-Authorization, Proxy-Features, Proxy-Instruction, Public, RWS, Range, Referer, Refresh, Resolution-Hint, Resolver-Location, Retry-After, Safe, Sec-Websocket-Extensions, Sec-Websocket-Key, Sec-Websocket-Origin, Sec-Websocket-Protocol, Sec-Websocket-Version, Security-Scheme, Server, Set-Cookie, Set-Cookie2, SetProfile, SoapAction, Status, Status-URI, Strict-Transport-Security, SubOK, Subst, Surrogate-Capability, Surrogate-Control, TCN, TE, TRACE, Timeout, Title, Trailer, Transfer-Encoding, UA-Color, UA-Media, UA-Pixels, UA-Resolution, UA-Windowpixels, URI, Upgrade, User-Agent, Variant-Vary, Vary, Version, Via, Viewport-Width, WWW-Authenticate, Want-Digest, Warning, Width, X-Content-Duration, X-Content-Security-Policy, X-Content-Type-Options, X-CustomHeader, X-DNSPrefetch-Control, X-Forwarded-For, X-Forwarded-Port, X-Forwarded-Proto, X-Frame-Options, X-Modified, X-OTHER, X-PING, X-PINGOTHER, X-Powered-By, X-Requested-With"
  Header set   Access-Control-Allow-Methods       "CONNECT, DEBUG, DELETE, DONE, GET, HEAD, HTTP, HTTP/0.9, HTTP/1.0, HTTP/1.1, HTTP/2, OPTIONS, ORIGIN, ORIGINS, PATCH, POST, PUT, QUIC, REST, SESSION, SHOULD, SPDY, TRACE, TRACK"
  Header set   Access-Control-Allow-Credentials   "true"

  Header set DNT "0"
  Header set Accept-Ranges "bytes"
  Header set Vary "Accept-Encoding"
  Header set X-UA-Compatible "IE=edge,chrome=1"
  Header set X-Frame-Options "SAMEORIGIN"
  Header set X-Content-Type-Options "nosniff"
  Header set X-Xss-Protection "1; mode=block"
</IfModule>

常见问题解答:

为什么Access-Control-Allow-HeadersAccess-Control-Expose-HeadersAccess-Control-Allow-Methods 的值超长?

那些不支持* 语法,所以我从网络上收集了最常见的(和奇异的)标题,各种格式#1#2#3(我会不时更新列表)

为什么要使用Header unset ______ 语法?

GoDaddy 服务器(我的网站托管在其上..)有一个奇怪的错误,如果标头已经设置,以前的值将加入现有的..(而不是替换它)这样我“预先清理" 现有值(真的只是一个快速&&肮脏解决方案)

按原样使用对我来说安全吗?

嗯.. 大部分答案是YES,因为.htaccess 将标头限制为脚本(php、HTML、...)和资源(.JPG、.JS、. CSS)从以下“文件夹”位置提供。您可以选择删除Access-Control-Allow-Methods 行。 还有ConnectionTime-ZoneKeep-AliveDNTAccept-RangesVaryX-UA-CompatibleX-Frame-OptionsX-Content-Type-OptionsX-Xss-Protection只是一个建议用于我的在线服务..也可以随意删除它们...

取自我的comment above

【讨论】:

这绝对救了我的命。我正在使用启用了 CORS 的 CDN 提供商,并且我在我的网站中使用 Access-Control-Allow-Origin "*" 允许它,但在我使用它之前没有任何效果。甚至 CDN 提供商也没有为我们提供答案。我在 Siteground 中运行网站,也许作为 GoDaddy,必须先取消设置所有内容。 优秀的帖子,应该顶到本页顶部。 在我的具体情况下,我必须从Access-Control-Allow-Methods 中删除所有这些方法:HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2 HTTP/2 甚至是有效的“方法”吗?从 HTTP/1.1 升级到 2 是否像那样工作?如果我看这里:sookocheff.com/post/networking/how-does-http-2-work HTTP/... 部分应该作为放置方法的第三位,而不是第一位。 也许要支持 HTTP/2.0 你需要添加 'PRI' 方法?【参考方案3】:

我发现 Access-Control-Allow-Headers: * 应该只为 OPTIONS 请求设置。 如果您为 POST 请求返回它,则浏览器会取消请求(至少对于 chrome)

以下 PHP 代码适用于我

// Allow CORS
if (isset($_SERVER['HTTP_ORIGIN'])) 
    header("Access-Control-Allow-Origin: $_SERVER['HTTP_ORIGIN']");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
   
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') 
    header("Access-Control-Allow-Headers: *");

我发现类似的问题有一些误导性的回答:

服务器线程说这是 2 年的 chrome 错误:Access-Control-Allow-Headers 与 localhost 不匹配。错了:我可以通过 Post 正常使用 CORS 到我的本地服务器 Access-Control-Allow-Headers 接受通配符。也错了,通配符对我有用(我只用 Chrome 测试过)

这需要我半天时间才能解决问题。

愉快的编码

【讨论】:

Wildcard("Access-Control-Allow-Headers: *") 在 Safari 7.0.4 上对我不起作用。 我发现在 Chrome 版本 40.0.2214.111 m 中设置 Access-Control-Allow-Headers 适用于 POST。 这似乎不对......规范不允许在Access-Control-Allow-Headers 上使用*,即使是OPTIONS【参考方案4】:

引自 monsur,

Access-Control-Allow-Headers 标头不允许使用通配符。它 必须完全匹配: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header.

所以这是我的 php 解决方案。

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') 
  header('Access-Control-Allow-Headers: ' . 
  $_SERVER['HTTP_ACCESS_CONTROL_ALLOW_HEADERS']);

【讨论】:

其实,何不干脆header('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_ALLOW_HEADERS']); 感谢您的建议。我已经更新了我的答案。【参考方案5】:

这是 nginx 的咒语,在一个

里面
location / 
    # Simple requests
    if ($request_method ~* "(GET|POST)") 
      add_header "Access-Control-Allow-Origin"  *;
    

    # Preflighted requests
    if ($request_method = OPTIONS ) 
      add_header "Access-Control-Allow-Origin"  *;
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
      add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
    


【讨论】:

【参考方案6】:

我被绊倒了,因为我真正想要的是一个稍微不同的标题。

access-control-ALLOW-headers 仅适用于飞行前请求。 MDN Docs access-control-EXPOSE-headers 适用于请求本身,这意味着 javascript 可以读取此处声明的标头。这就是我需要的。 MDN Docs

我知道这是切线相关的,但我希望它对某人有所帮助。

【讨论】:

以上是关于CORS Access-Control-Allow-Headers 通配符被忽略?的主要内容,如果未能解决你的问题,请参考以下文章

cors技术

ExpressJS 不同的域名 - CORS

在哪里启用cors?

在 Golang 中启用 CORS

Express 中间件未设置 CORS 标头

使用 CORS 的 Javascript 和 angularjs