Curva de access-controle-permitir-headers Cors sendo ignorado?

Estou tendo problemas para fazer com que uma solicitação de cors de vários domínios funcione corretamente usando o chrome.

Solicitar headers:

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 

Cabeçalhos de resposta:

 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 

Erro:

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

E o código python que atende a solicitação de opçõ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 o curinga Access-Control-Allow-Origin está sendo ignorado?

O suporte a curingas no header Access-Control-Allow-Headers foi adicionado ao padrão de vida apenas em maio de 2016, portanto, pode não ser suportado por todos os navegadores. No navegador que ainda não implementa isso, deve ser uma correspondência exata: https://www.w3.org/TR/2014/REC-cors-20140116/#access-control-allow-headers-response-header

Se você espera um grande número de headers, é possível ler o valor do header Access-Control-Request-Headers e ecoar esse valor no header Access-Control-Allow-Headers .

Esses headers CORS não suportam * como valor, a única maneira é replace * por isso:

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


Exemplo de .htaccess (CORS incluído):

  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"  

PERGUNTAS FREQUENTES:

  • Por que os valores Access-Control-Allow-Headers , Access-Control-Expose-Headers e Access-Control-Allow-Methods são super longos?

    Aqueles não suportam a syntax * , então colecionei os headers mais comuns (e exóticos) da web, em vários formatos # 1 # 2 # 3 (e atualizarei a lista de tempos em tempos)

  • Por que você usa a syntax de Header unset ______ ?

    Servidores GoDaddy (que meu site está hospedado em ..) tem um bug estranho onde se os headers já estão definidos, o valor anterior irá juntar-se ao já existente .. (em vez de substituí-lo) desta forma eu “pre-clean” valores existentes (realmente apenas aa solução rápida e suja )

  • É seguro para mim usar ‘como está’?

    Bem … principalmente a resposta seria SIM, pois o .htaccess está limitando os headers aos scripts (PHP, HTML, …) e resources (.JPG, .JS, .CSS) servidos a partir da seguinte “pasta” -localização . Opcionalmente, você pode querer remover as linhas Access-Control-Allow-Methods . Também Connection , Time-Zone , Keep-Alive e DNT , Accept-Ranges , Vary , X-UA-Compatible , X-Frame-Options , X-Content-Type-Options e X-Xss-Protection são apenas uma sugestão que eu m usando para o meu serviço on-line .. sinta-se livre para removê-los também …

tirado do meu comentário acima

Descobri que Access-Control-Allow-Headers: * deve ser definido SOMENTE para a solicitação “OPTIONS”. Se você devolvê-lo para solicitação POST, então o navegador cancelará a solicitação (pelo menos para chrome)

O seguinte código PHP funciona para mim

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

Eu encontrei perguntas semelhantes com alguma resposta enganosa:

  • Tópico do servidor diz que este é um erro de 2 anos do chrome: Access-Control-Allow-Headers não combina com o localhost. Está errado: eu posso usar CORS para o meu servidor local com Post normalmente
  • Access-Control-Allow-Headers aceita curingas. Também está errado, o curinga funciona para mim (testei apenas com o Chrome)

Isso me leva meio dia para descobrir o problema.

Codificação feliz

Citado de monsur,

O header Access-Control-Allow-Headers não permite curingas. Deve ser uma correspondência exata: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header .

Então aqui está a minha solução de php.

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

aqui está o encantamento para o nginx, dentro de um

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