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


118

我在跨域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通配符被忽略了吗?

Answers:


185

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

如果期望大量的标头,则可以读入Access-Control-Request-Headers标头的值并在标头中回显该值Access-Control-Allow-Headers


55
resp.setHeader(“ Access-Control-Allow-Headers”,req.getHeader(“ Access-Control-Request-Headers”)); //允许任何标头
Sam Barnum

3
在红宝石上,“如果request.headers ['Access-Control-Request-Headers']然后headers ['Access-Control-Allow-Headers'] = request.headers ['Access-Control-Request-Headers']结尾”我可以。
2014年

1
@monsur:这个答案指出,至少在理论上,现在允许使用通配符,因此我更新了您的答案以反映这一点。如果您不喜欢我的风格,请随时根据自己的喜好进行编辑。
MvG

2
提示一下,如果您还允许浏览器缓存预检响应(使用Access-Control-Max-Age),则可能依赖传回Access-Control-Request-Headers值而遇到麻烦。您不知道第一个请求列出了连续请求的所有标头。
Simon Ejsing

2
@monokrome如果您能告诉我们在生产中如何解决安全问题,
那就太好了。– prettyvoid

52

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

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服务器(我的网站托管于此)上有一个怪异的错误,如果已设置标头,则以前的值将加入现有的值(而不是替换它),这样我可以“预先清理”现有的值(真的只是一个快速和肮脏的解决方案)

  • 我按原样使用安全吗?

    好吧..大多数答案是肯定的,因为它将.htaccess标头限制为从以下“文件夹”位置提供服务的脚本(PHP,HTML等)和资源(.JPG,.JS,.CSS)。您可以选择删除Access-Control-Allow-Methods行。此外ConnectionTime-ZoneKeep-AliveDNTAccept-RangesVaryX-UA-CompatibleX-Frame-OptionsX-Content-Type-OptionsX-Xss-Protection只是我使用我的在线服务的建议..随意删除这些呢?

摘自我上面的评论


这无疑挽救了我的生命。我使用的是CDN提供程序,并且启用了CORS,而且我在我的网站中允许使用它,Access-Control-Allow-Origin "*"但直到我使用它,它都无法正常工作。甚至CDN提供商也没有答案。我在Siteground中运行网站,也许是GoDaddy,必须先取消所有设置。
伊格纳西奥·布斯托斯

优秀的帖子,应该在此页面顶部显示。
CommonKnowledge18年

1
在我的特定情况下,我必须从Access-Control-Allow-Methods所有这些方法中删除:HTTP / 0.9,HTTP / 1.0,HTTP / 1.1,HTTP / 2
umbe1987 '18

HTTP / 2甚至是有效的“方法”吗?从HTTP / 1.1升级到2是否可以那样工作?如果我看这里:sookocheff.com/post/networking/how-does-http-2-work HTTP / ...部分应该放在放置方法的第三位,而不是第一位。
Henk Poley

也许要支持HTTP / 2.0,您需要添加“ PRI”方法吗?
Henk Poley

17

我发现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: *");
}

我发现了类似的问题,但做出了一些误导性的回答:

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

这花了我半天的时间来解决问题。

快乐编码


2
在Safari 7.0.4上,通配符(“ Access-Control-Allow-Headers:*”)对我不起作用。
2014年

我发现在Chrome版本40.0.2214.111 m中,设置Access-Control-Allow-Headers适用于POST。
Derek Greer

3
这似乎并不正确.....该规范不允许*Access-Control-Allow-Headers甚至OPTIONS
Pacerier '16

1

引用monsur的话,

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

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

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  $headers=getallheaders();
  @$ACRH=$headers["Access-Control-Request-Headers"];
  header("Access-Control-Allow-Headers: $ACRH");
}

1
实际上,为什么不简单header('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_ALLOW_HEADERS']);
Pacerier '16

0

这是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";
    }

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.