¿Se está ignorando el comodín Cors Access-Control-Allow-Headers?

Tengo problemas para que una solicitud de dominios de dominio cruzado funcione correctamente con Chrome.

Encabezados de solicitud:

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 

Encabezados de respuesta:

 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. 

Y el código python que sirve la solicitud de opciones es:

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

Parece que se está ignorando el comodín Access-Control-Allow-Origin?

El soporte para comodines en el Access-Control-Allow-Headers se agregó al estándar de vida solo en mayo de 2016, por lo que es posible que no sea compatible con todos los navegadores. En el navegador que aún no implementa esto, debe ser una coincidencia exacta: https://www.w3.org/TR/2014/REC-cors-20140116/#access-control-allow-headers-response-header

Si espera una gran cantidad de encabezados, puede leer el valor del Access-Control-Request-Headers y repetir ese valor en el Access-Control-Allow-Headers .

Esos encabezados CORS no admiten * como valor, la única forma es reemplazar * con esto:

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


Ejemplo de .htaccess (CORS incluido):

  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"  

PREGUNTAS MÁS FRECUENTES:

  • ¿Por qué los valores de Access-Control-Allow-Headers , Access-Control-Expose-Headers , Access-Control-Allow-Methods son muy largos?

    Esos no son compatibles con la * syntax, por lo que he recostackdo los encabezados más comunes (y exóticos) de toda la web, en varios formatos # 1 # 2 # 3 (y actualizaré la lista de vez en cuando)

  • ¿Por qué usas Header unset ______ syntax?

    Los servidores GoDaddy (en los que está alojado mi sitio web) tienen un error extraño donde si los encabezados ya están configurados, el valor anterior se unirá al existente … (en lugar de reemplazarlo) de esta forma “pre-limpie” los valores existentes (realmente solo una solución rápida y sucia )

  • ¿Es seguro para mí usar ‘tal cual’?

    Bueno … en su mayoría, la respuesta sería SÍ, ya que .htaccess limita los encabezados a los scripts (PHP, HTML, …) y los recursos (.JPG, .JS, .CSS) servidos desde la siguiente “carpeta” – ubicación . Opcionalmente, es posible que desee eliminar las líneas de Access-Control-Allow-Methods . También Connection , Time-Zone , Keep-Alive y DNT , Accept-Ranges , Vary , X-UA-Compatible , X-Frame-Options , X-Content-Type-Options y X-Xss-Protection son solo una sugerencia. Estoy usando mi servicio en línea. Siéntase libre de eliminarlos también …

tomado de mi comentario anterior

Encontré que Access-Control-Allow-Headers: * debe establecerse SOLAMENTE para la solicitud de “OPCIONES”. Si lo devuelve para la solicitud POST, el navegador cancelará la solicitud (al menos para Chrome)

El siguiente código PHP funciona para mí

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

Encontré preguntas similares con alguna respuesta engañosa:

  • El hilo del servidor dice que esto es 2 años de error de Chrome: Access-Control-Allow-Headers no coincide con localhost. Está mal: puedo usar CORS en mi servidor local con Post normalmente
  • Access-Control-Allow-Headers acepta comodines. También es incorrecto, el comodín funciona para mí (lo probé solo con Chrome)

Esto me toma medio día para resolver el problema.

Feliz encoding

Citado de monsur,

El encabezado Access-Control-Allow-Headers no permite comodines. Debe ser una coincidencia exacta: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header .

Así que aquí está mi solución php.

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

aquí está el encantamiento para nginx, dentro de un

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