Nell'indagine di seguito come API, utilizzo http://example.com invece di http: // myApiUrl / login dalla tua domanda, perché questa prima funziona.
Presumo che la tua pagina sia su http: //my-site.local: 8088 .
Il motivo per cui vedi risultati diversi è che Postman:
- imposta intestazione
Host=example.com
(la tua API)
- NON impostare l'intestazione
Origin
Questo è simile al modo in cui i browser inviano le richieste quando il sito e l'API hanno lo stesso dominio (i browser impostano anche l'elemento di intestazione Referer=http://my-site.local:8088
, tuttavia non lo vedo in Postman). Quando l' Origin
intestazione non è impostata, generalmente i server consentono tali richieste per impostazione predefinita.
Questo è il modo standard in cui Postman invia le richieste. Ma un browser invia richieste in modo diverso quando il sito e l'API hanno domini diversi , quindi si verifica CORS e il browser automaticamente:
- imposta l'intestazione
Host=example.com
(la tua come API)
- imposta l'intestazione
Origin=http://my-site.local:8088
(il tuo sito)
(L'intestazione Referer
ha lo stesso valore di Origin
). E ora nella scheda Console e reti di Chrome vedrai:
Quando hai Host != Origin
questo è CORS, e quando il server rileva tale richiesta, di solito lo blocca per impostazione predefinita .
Origin=null
viene impostato quando si apre contenuto HTML da una directory locale e invia una richiesta. La stessa situazione è quando si invia una richiesta all'interno di un <iframe>
, come nello snippet di seguito (ma qui l' Host
intestazione non è impostata affatto) - in generale, ovunque la specifica HTML dice origine opaca, è possibile tradurla in Origin=null
. Ulteriori informazioni al riguardo sono disponibili qui .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Se non si utilizza una semplice richiesta CORS, in genere il browser invia automaticamente anche una richiesta OPTIONS prima di inviare la richiesta principale: ulteriori informazioni sono disponibili qui . Lo snippet di seguito lo 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)
È possibile modificare la configurazione del server per consentire le richieste CORS.
Ecco una configurazione di esempio che attiva CORS su nginx (file nginx.conf) - fai molta attenzione alle impostazioni always/"$http_origin"
per nginx e "*"
per Apache - questo sbloccherà CORS da qualsiasi dominio.
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;
}
}
Ecco una configurazione di esempio che attiva CORS su Apache (file .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"