Platzhalter für CORS Access-Control-Allow-Headers wird ignoriert?

118

Ich habe Probleme, eine domänenübergreifende CORS-Anfrage zu erhalten, damit sie mit Chrome ordnungsgemäß funktioniert.

Header anfordern:

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

Antwortheader:

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

Error:

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

Der Python-Code für die Optionsanforderung lautet:

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()

Es scheint, dass der Access-Control-Allow-OriginPlatzhalter ignoriert wird?

Ben Reeves
quelle

Antworten:

185

Die Unterstützung für Platzhalter in der Access-Control-Allow-HeadersKopfzeile wurde erst im Mai 2016 zum Lebensstandard hinzugefügt , sodass sie möglicherweise nicht von allen Browsern unterstützt wird. Bei Browsern, die dies noch nicht implementieren, muss es genau übereinstimmen: https://www.w3.org/TR/2014/REC-cors-20140116/#access-control-allow-headers-response-header

Wenn Sie eine große Anzahl von Headern erwarten, können Sie den Wert des Access-Control-Request-HeadersHeaders einlesen und diesen Wert im Access-Control-Allow-HeadersHeader wiedergeben.

Monsur
quelle
55
resp.setHeader ("Access-Control-Allow-Header", req.getHeader ("Access-Control-Request-Header")); // Erlaube irgendwelche Header
Sam Barnum
3
Auf Ruby sieht "wenn request.headers ['Access-Control-Request-Header'] dann Header ['Access-Control-Allow-Headers'] = request.headers ['Access-Control-Request-Headers'] end" aus OK für mich.
Tsuneo Yoshioka
1
@monsur: In dieser Antwort wurde darauf hingewiesen, dass Platzhalter jetzt zumindest theoretisch zulässig sind. Daher habe ich Ihre Antwort aktualisiert, um dies widerzuspiegeln. Wenn Sie meinen Stil nicht mögen, können Sie ihn nach Ihrem Geschmack bearbeiten.
MvG
2
Ein Wort der Warnung: Sie können Probleme bekommen, wenn Sie den Wert Access-Control-Request-Headers zurückgeben, wenn Sie dem Browser auch erlauben, die Preflight-Antwort zwischenzuspeichern (mit Access-Control-Max-Age). Sie wissen nicht, dass die erste Anforderung alle Header aufeinanderfolgender Anforderungen auflistet.
Simon Ejsing
2
@monokrome wäre toll, wenn Sie uns sagen können, wie dies ein Sicherheitsrisiko in der Produktion wäre ..
ziemlich leer
52

Diese CORS-Header werden nicht *als Wert unterstützt. Der einzige Weg besteht darin, Folgendes zu ersetzen *:

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 Beispiel (CORS enthalten):

<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>

FAQ:

  • Warum Access-Control-Allow-Headers, Access-Control-Expose-Headers, Access-Control-Allow-Methodssind super lange Werte?

    Diese unterstützen die *Syntax nicht, daher habe ich die häufigsten (und exotischsten) Header aus dem Internet in verschiedenen Formaten # 1 # 2 # 3 gesammelt (und ich werde die Liste von Zeit zu Zeit aktualisieren).

  • Warum verwenden Sie Header unset ______Syntax?

    GoDaddy-Server (auf denen meine Website gehostet wird ..) haben einen seltsamen Fehler: Wenn die Header bereits festgelegt sind, wird der vorherige Wert mit dem vorhandenen Wert verbunden. (Anstatt ihn zu ersetzen) Auf diese Weise "bereinige" ich vorhandene Werte (wirklich nur eine schnelle && schmutzige Lösung)

  • Ist es für mich sicher, "wie besehen" zu verwenden?

    Nun ... meistens wäre die Antwort JA, da die .htaccessHeader auf die Skripte (PHP, HTML, ...) und Ressourcen (.JPG, .JS, .CSS) beschränkt sind, die von der folgenden "Ordner" -Lage bereitgestellt werden. Optional möchten Sie möglicherweise die Access-Control-Allow-MethodsZeilen entfernen . Auch Connection, Time-Zone, Keep-Aliveund DNT, Accept-Ranges, Vary, X-UA-Compatible, X-Frame-Options, X-Content-Type-Optionsund X-Xss-Protectionist nur ein Vorschlag Ich bin für meinen Online-Service mit .. fühlen sich frei , diejenigen zu entfernen ...

entnommen aus meinem Kommentar oben

Gemeinschaft
quelle
Das hat mir definitiv das Leben gerettet. Ich habe einen CDN-Anbieter mit aktiviertem CORS verwendet und es auch auf meiner Website zugelassen, Access-Control-Allow-Origin "*"aber nichts hat funktioniert, bis ich dies verwendet habe. Nicht einmal der CDN-Anbieter hatte eine Antwort für uns. Ich betreibe die Website in Siteground , vielleicht ist es als GoDaddy obligatorisch, zuerst alles zu deaktivieren.
Ignacio Bustos
Ausgezeichneter Beitrag, dieser sollte oben auf dieser Seite angezeigt werden.
CommonKnowledge
1
In meinem speziellen Fall musste ich aus Access-Control-Allow-Methodsall diesen Methoden entfernen : HTTP / 0.9, HTTP / 1.0, HTTP / 1.1, HTTP / 2
umbe1987
Ist HTTP / 2 überhaupt eine gültige Methode? Funktioniert ein Upgrade von HTTP / 1.1 auf 2 so oder so? Wenn ich hier schaue: sookocheff.com/post/networking/how-does-http-2-work Der HTTP / ... Teil soll als dritter Platz gehen, nicht als erster, wo die Methode platziert wird.
Henk Poley
Möglicherweise müssen Sie zur Unterstützung von HTTP / 2.0 die PRI-Methode hinzufügen?
Henk Poley
17

Ich fand, dass Access-Control-Allow-Headers: *dies NUR für die OPTIONS-Anfrage eingestellt werden sollte. Wenn Sie es für eine POST-Anfrage zurücksenden, bricht der Browser die Anfrage ab (zumindest für Chrome).

Der folgende PHP-Code funktioniert für mich

// 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: *");
}

Ich fand ähnliche Fragen mit einer irreführenden Antwort:

  • Server-Thread sagt, dass dies 2 Jahre Chrome-Fehler ist: Access-Control-Allow-Headersstimmt nicht mit localhost überein. Es ist falsch: Ich kann CORS mit Post normal auf meinem lokalen Server verwenden
  • Access-Control-Allow-Headersakzeptiert Platzhalter. Es ist auch falsch, Wildcard funktioniert für mich (ich habe nur mit Chrome getestet)

Ich brauche einen halben Tag, um das Problem herauszufinden.

Viel Spaß beim Codieren

Greensuisse
quelle
2
Der Platzhalter ("Access-Control-Allow-Headers: *") funktionierte bei Safari 7.0.4 nicht.
Tsuneo Yoshioka
Ich habe festgestellt, dass das Festlegen von Access-Control-Allow-Headern für POST in Chrome Version 40.0.2214.111 m funktioniert.
Derek Greer
3
Dies scheint nicht richtig ..... Die Spezifikation nicht erlaubt *auf Access-Control-Allow-Headerssogar OPTIONS.
Pacerier
1

Zitiert aus Monsur,

Der Header Access-Control-Allow-Headers erlaubt keine Platzhalter. Es muss genau übereinstimmen: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header .

Also hier ist meine PHP-Lösung.

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  $headers=getallheaders();
  @$ACRH=$headers["Access-Control-Request-Headers"];
  header("Access-Control-Allow-Headers: $ACRH");
}
Jason Chiang
quelle
1
Eigentlich, warum nicht einfachheader('Access-Control-Allow-Headers: ' . $_SERVER['HTTP_ACCESS_CONTROL_ALLOW_HEADERS']);
Pacerier
0

Hier ist die Beschwörung für Nginx in a

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

}
dcsan
quelle