Na investigação abaixo como API, uso http://example.com em vez de http: // myApiUrl / login da sua pergunta, porque esta primeira está funcionando.
Presumo que sua página esteja em http: //my-site.local: 8088 .
A razão pela qual você vê resultados diferentes é que o Postman:
- definir cabeçalho
Host=example.com
(sua API)
- NÃO definir cabeçalho
Origin
Isso é semelhante à maneira como os navegadores enviam solicitações quando o site e a API têm o mesmo domínio (os navegadores também definem o item de cabeçalho Referer=http://my-site.local:8088
, mas não o vejo no Postman). Quando o Origin
cabeçalho não está definido, geralmente os servidores permitem tais solicitações por padrão.
Esta é a maneira padrão como o Postman envia solicitações. Mas um navegador envia solicitações de maneira diferente quando o site e a API têm domínios diferentes e, em seguida, ocorre o CORS e o navegador automaticamente:
- define o cabeçalho
Host=example.com
(o seu como API)
- define o cabeçalho
Origin=http://my-site.local:8088
(seu site)
(O cabeçalho Referer
tem o mesmo valor que Origin
). E agora, na guia Console e redes do Chrome, você verá:
Quando você tem Host != Origin
o CORS, e quando o servidor detecta essa solicitação, geralmente a bloqueia por padrão .
Origin=null
é definido quando você abre o conteúdo HTML de um diretório local e envia uma solicitação. A mesma situação é quando você envia uma solicitação dentro de um <iframe>
, como no snippet abaixo (mas aqui o Host
cabeçalho não está definido) - em geral, em todos os lugares em que a especificação HTML diz origem opaca, você pode traduzir isso para Origin=null
. Mais informações sobre isso você pode encontrar aqui .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Se você não usar uma solicitação CORS simples, geralmente o navegador também envia automaticamente uma solicitação OPTIONS antes de enviar a solicitação principal - mais informações estão aqui . O snippet abaixo mostra:
fetch('http://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)
Você pode alterar a configuração do seu servidor para permitir solicitações CORS.
Aqui está um exemplo de configuração que ativa o CORS no nginx (arquivo nginx.conf) - tenha muito cuidado com a configuração always/"$http_origin"
do nginx e "*"
do Apache - isso desbloqueará o CORS de qualquer domínio.
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Aqui está um exemplo de configuração que ativa o CORS no Apache (arquivo .htaccess)
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"
Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"