En la investigación a continuación como API, uso http://example.com en lugar de http: // myApiUrl / login de su pregunta, porque esta primera funciona.
Supongo que su página está en http: //my-site.local: 8088 .
La razón por la que ves resultados diferentes es que Postman:
- establecer encabezado
Host=example.com
(su API)
- NO establecer encabezado
Origin
Esto es similar a la forma en que los navegadores envían solicitudes cuando el sitio y la API tienen el mismo dominio (los navegadores también configuran el elemento del encabezado Referer=http://my-site.local:8088
, sin embargo, no lo veo en Postman). Cuando el Origin
encabezado no está configurado, generalmente los servidores permiten tales solicitudes de forma predeterminada.
Esta es la forma estándar en que Postman envía solicitudes. Pero un navegador envía solicitudes de manera diferente cuando su sitio y API tienen dominios diferentes , y luego se produce CORS y el navegador automáticamente:
- establece el encabezado
Host=example.com
(el suyo como API)
- establece encabezado
Origin=http://my-site.local:8088
(su sitio)
(El encabezado Referer
tiene el mismo valor que Origin
). Y ahora, en la pestaña Consola y redes de Chrome, verá:
Cuando tiene Host != Origin
esto es CORS, y cuando el servidor detecta dicha solicitud, generalmente la bloquea de manera predeterminada .
Origin=null
se establece cuando abre contenido HTML desde un directorio local y envía una solicitud. La misma situación es cuando envía una solicitud dentro de un <iframe>
, como en el fragmento a continuación (pero aquí el Host
encabezado no está configurado en absoluto); en general, en todos los lugares donde la especificación HTML dice origen opaco, puede traducir eso Origin=null
. Puede encontrar más información sobre esto aquí .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Si no utiliza una solicitud CORS simple, generalmente el navegador también envía automáticamente una solicitud de OPCIONES antes de enviar la solicitud principal; aquí encontrará más información . El fragmento a continuación lo muestra:
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)
Puede cambiar la configuración de su servidor para permitir solicitudes CORS.
Aquí hay un ejemplo de configuración que activa CORS en nginx (archivo nginx.conf) - tenga mucho cuidado con la configuración always/"$http_origin"
de nginx y "*"
Apache - esto desbloqueará CORS de cualquier 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;
}
}
Aquí hay una configuración de ejemplo que activa CORS en Apache (archivo .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"