Aparentemente, he entendido completamente su semántica. Pensé en algo como esto:
- Un cliente descarga el código JavaScript MyCode.js desde
http://siteA
- el origen . - El encabezado de respuesta de MyCode.js contiene Access-Control-Allow-Origin:
http://siteB
lo que pensé que significaba que MyCode.js podía hacer referencias de origen cruzado al sitio B. - El cliente activa alguna funcionalidad de MyCode.js, que a su vez realiza solicitudes a
http://siteB
, lo que debería estar bien, a pesar de ser solicitudes de origen cruzado.
Pues estoy equivocado. No funciona así en absoluto. Entonces, leí el uso compartido de recursos de origen cruzado e intenté leer el uso compartido de recursos de origen cruzado en la recomendación w3c
Una cosa es segura: todavía no entiendo cómo se supone que debo usar este encabezado.
Tengo control total del sitio A y del sitio B. ¿Cómo habilito el código javascript descargado del sitio A para acceder a los recursos del sitio B usando este encabezado?
PD
No quiero utilizar JSONP.
javascript
cross-domain
cors
marca
fuente
fuente
http://siteA/MyCode.js
.Respuestas:
Access-Control-Allow-Origin
es un encabezado CORS (Cross-Origin Resource Sharing) .Cuando el sitio A intenta obtener contenido del sitio B, el sitio B puede enviar un
Access-Control-Allow-Origin
encabezado de respuesta para indicarle al navegador que el contenido de esta página es accesible para ciertos orígenes. (Un origen es un dominio, más un esquema y un número de puerto ). Por defecto, las páginas del Sitio B no son accesibles a ningún otro origen ; El uso delAccess-Control-Allow-Origin
encabezado abre una puerta para el acceso de origen cruzado por orígenes solicitantes específicos.Para cada recurso / página que el Sitio B quiere hacer accesible al Sitio A, el Sitio B debe servir sus páginas con el encabezado de respuesta:
Los navegadores modernos no bloquearán directamente las solicitudes de dominio cruzado. Si el sitio A solicita una página del sitio B, el navegador realmente buscará la página solicitada en el nivel de red y verificará si los encabezados de respuesta enumeran el sitio A como un dominio solicitante permitido. Si el sitio B no ha indicado que el sitio A puede acceder a esta página, el navegador activará el evento
XMLHttpRequest
delerror
evento y denegará los datos de respuesta al código JavaScript que lo solicita.Peticiones no simples
Lo que sucede a nivel de red puede ser un poco más complejo que lo explicado anteriormente. Si la solicitud es una solicitud "no simple" , el navegador primero envía una solicitud de OPCIONES "previa al vuelo" sin datos, para verificar que el servidor aceptará la solicitud. Una solicitud no es simple cuando cualquiera (o ambos):
Accept
Accept-Language
Content-Language
Content-Type
(esto sólo es simple cuando su valor esapplication/x-www-form-urlencoded
,multipart/form-data
otext/plain
)Si el servidor responde a la verificación previa de OPCIONES con encabezados de respuesta apropiados (
Access-Control-Allow-Headers
para encabezados no simples,Access-Control-Allow-Methods
para verbos no simples) que coinciden con el verbo no simple y / o encabezados no simples, entonces el navegador envía la solicitud real.Suponiendo que el Sitio A quiere enviar una solicitud PUT para
/somePage
, con unContent-Type
valor no simple deapplication/json
, el navegador primero enviará una solicitud de verificación previa:Tenga en cuenta que
Access-Control-Request-Method
yAccess-Control-Request-Headers
se añaden automáticamente por el navegador; No es necesario agregarlos. Esta verificación previa de OPCIONES obtiene los encabezados de respuesta exitosos:Al enviar la solicitud real (después de que se realiza la verificación previa), el comportamiento es idéntico a cómo se maneja una solicitud simple. En otras palabras, una solicitud no simple cuya verificación previa es exitosa se trata de la misma manera que una solicitud simple (es decir, el servidor aún debe enviar
Access-Control-Allow-Origin
nuevamente la respuesta real).Los navegadores envían la solicitud real:
Y el servidor devuelve un
Access-Control-Allow-Origin
, tal como lo haría para una simple solicitud:Consulte Comprender XMLHttpRequest sobre CORS para obtener un poco más de información sobre solicitudes no simples.
fuente
Access-Control-Allow-Origin
encabezado, pero podría no proporcionar la respuesta al código JS en el sitio A si el encabezado no permite que el sitio A lo tenga. (PD Gracias :))Access-Control-Allow-Origin
no acepta la*
en algunos navegadores (FF y Chrome AFAIK). Entonces, en este caso, debe especificar el valor delOrigin
encabezado. Espero que esto ayude a alguien.Intercambio de recursos de origen cruzado:
CORS
(solicitud AKA de dominio cruzado AJAX) es un problema que la mayoría de los desarrolladores web pueden encontrar, de acuerdo con la Política de Mismo Origen, los navegadores restringen el JavaScript del cliente en un entorno limitado de seguridad, generalmente JS no puede comunicarse directamente con un servidor remoto de un dominio diferente. En el pasado, los desarrolladores crearon muchas formas difíciles de lograr la solicitud de recursos entre dominios.Esas formas complicadas tienen más o menos algunos problemas, por ejemplo, JSONP podría resultar en un agujero de seguridad si los desarrolladores simplemente lo "evalúan", y el # 3 anterior, aunque funciona, ambos dominios deben construir un contrato estricto entre sí, ni flexible ni elegante. EN MI HUMILDE OPINIÓN:)
El W3C había introducido Cross-Origin Resource Sharing (CORS) como una solución estándar para proporcionar una forma estándar segura, flexible y recomendada para resolver este problema.
El mecanismo
Desde un alto nivel, simplemente podemos considerar que CORS es un contrato entre la llamada AJAX del cliente del dominio A y una página alojada en el dominio B, una solicitud / respuesta típica de origen cruzado sería:
Dominio Un encabezado de solicitud AJAX
Encabezados de respuesta de DomainB
Las partes azules que marqué arriba eran los hechos del núcleo, el encabezado de solicitud "Origen" indica dónde se origina la solicitud de origen cruzado o la solicitud de verificación previa ", el encabezado de respuesta" Acceso-Control-Permitir-Origen "indica que esta página permite la solicitud remota de El dominio A (si el valor es * indica permite solicitudes remotas de cualquier dominio).
Como mencioné anteriormente, W3 recomendó que el navegador implementara una " solicitud de verificación previa " antes de enviar la solicitud HTTP Cross-Origin, en pocas palabras, es una
OPTIONS
solicitud HTTP :Si foo.aspx admite el verbo HTTP OPTIONS, podría devolver una respuesta como la siguiente:
Solo si la respuesta contiene "Access-Control-Allow-Origin" Y su valor es "*" o si contiene el dominio que envió la solicitud CORS, al satisfacer esta condición obligatoria, el navegador enviará la solicitud real entre dominios y almacenará en caché el resultado en " Preflight-Result-Cache ".
Hace un blog escribí sobre CORS hace tres años: solicitud HTTP AJAX Cross-Origin
fuente
La pregunta es un poco vieja para responderla, pero estoy publicando esto para cualquier referencia futura a esta pregunta.
De acuerdo con este artículo de Mozilla Developer Network,
Una página HTML servida desde
http://domain-a.com
hace una<img>
solicitud src parahttp://domain-b.com/image.jpg
.Muchas páginas en la web actualmente cargan recursos como hojas de estilo CSS , imágenes y scripts de dominios separados (por lo tanto, debería ser genial).
Política del mismo origen
Por razones de seguridad, los navegadores restringen las solicitudes HTTP de origen cruzado iniciadas desde scripts .
Por ejemplo,
XMLHttpRequest
yFetch
siga la política del mismo origen .Por lo tanto, una aplicación web que usa
XMLHttpRequest
oFetch
solo puede realizar solicitudes HTTP a su propio dominio .Intercambio de recursos de origen cruzado (CORS)
Para mejorar las aplicaciones web, los desarrolladores pidieron a los proveedores de navegadores que permitieran solicitudes entre dominios.
El mecanismo de intercambio de recursos de origen cruzado (CORS) brinda a los servidores web controles de acceso entre dominios , que permiten transferencias seguras de datos entre dominios.
Los navegadores modernos usan CORS en un contenedor API , como
XMLHttpRequest
oFetch
, para mitigar los riesgos de las solicitudes HTTP de origen cruzado.Cómo funciona CORS (
Access-Control-Allow-Origin
encabezado)Wikipedia :
Ejemplo
El navegador envía el
OPTIONS
solicitud con unOrigin HTTP
encabezado.El valor de este encabezado es el dominio que sirvió a la página principal. Cuando una página
http://www.example.com
intenta acceder a los datos de un usuario enservice.example.com
, se envía el siguiente encabezado de solicitud aservice.example.com
:Origen: http://www.example.com
El servidor en
service.example.com
puede responder con:Un
Access-Control-Allow-Origin
encabezado (ACAO) en su respuesta que indica qué sitios de origen están permitidos.Por ejemplo:
Access-Control-Allow-Origin: http://www.example.com
Una página de error si el servidor no permite la solicitud de origen cruzado
Un
Access-Control-Allow-Origin
encabezado (ACAO) con un comodín que permite todos los dominios:Access-Control-Allow-Origin: *
fuente
Access-Control-Allow-Origin:null
Access-Control-Allow-Origin
? Me refiero a la negación deAccess-Control-Allow-Origin: *
Cada vez que empiezo a pensar en CORS, mi intuición acerca de qué sitio aloja los encabezados es incorrecta, tal como lo describió en su pregunta. Para mí, ayuda pensar en el propósito de la misma política de origen.
El propósito de la misma política de origen es protegerlo de JavaScript malicioso en siteA.com accediendo a la información privada que ha elegido compartir solo con siteB.com. Sin la misma política de origen, JavaScript escrito por los autores de siteA.com podría hacer que su navegador haga solicitudes a siteB.com, utilizando sus cookies de autenticación para siteB.com. De esta manera, siteA.com podría robar la información secreta que comparte con siteB.com.
A veces es necesario trabajar entre dominios, que es donde entra CORS. CORS relaja la misma política de origen para domainB.com, utilizando el
Access-Control-Allow-Origin
encabezado para enumerar otros dominios (domainA.com) en los que se confía para ejecutar JavaScript que puede interactuar con domainA. com.Para comprender qué dominio debe servir a los encabezados CORS, considere esto. Usted visita Malware.com, que contiene JavaScript que intenta realizar una solicitud de dominio cruzado a mybank.com. Debería depender de mybank.com, no malévolo.com, decidir si establece o no los encabezados CORS que relajan la misma política de origen que permite que el JavaScript de malévolo.com interactúe con él. Si malicous.com pudiera establecer sus propios encabezados CORS permitiendo su propio acceso JavaScript a mybank.com, esto anularía por completo la misma política de origen.
Creo que la razón de mi mala intuición es el punto de vista que tengo al desarrollar un sitio. Es mi sitio, con todo mi JavaScript, por lo tanto, no está haciendo nada malicioso y debería depender de mí especificar con qué otros sitios puede interactuar mi JavaScript. ¿Cuándo debo pensar qué otros sitios JavaScript está tratando de interactuar con mi sitio y debo usar CORS para permitirlos?
fuente
1. Un cliente descarga el código de JavaScript MyCode.js desde http: // siteA - el origen.
El código que realiza la descarga, su etiqueta de script html o xhr de javascript o lo que sea, proviene de, digamos, http: // siteZ . Y, cuando el navegador solicita MyCode.js, envía un encabezado Origin: que dice "Origin: http: // siteZ ", porque puede ver que está solicitando siteA y siteZ! = SiteA. (No puede parar o interferir con esto).
2. El encabezado de respuesta de MyCode.js contiene Access-Control-Allow-Origin: http: // siteB , que pensé que significaba que MyCode.js podía hacer referencias de origen cruzado al sitio B.
No. Significa que solo el sitio B puede hacer esta solicitud. Por lo tanto, su solicitud de MyCode.js de siteZ obtiene un error en su lugar, y el navegador generalmente no le da nada. Pero si hace que su servidor devuelva ACAO: siteZ en su lugar, obtendrá MyCode.js. O si envía '*', eso funcionará, dejará entrar a todos. O si el servidor siempre envía la cadena desde el origen: encabezado ... pero ... por seguridad, si tienes miedo de los piratas informáticos , su servidor solo debe permitir orígenes en una lista restringida, que pueden realizar esas solicitudes.
Entonces, MyCode.js proviene del sitio A. Cuando realiza solicitudes al sitio B, todas son de origen cruzado, el navegador envía Origen: sitioA, y el sitio B tiene que tomar el sitio A, reconocer que está en la lista corta de solicitantes permitidos y devolver ACAO: sitio A. Solo entonces el navegador permitirá que su script obtenga el resultado de esas solicitudes.
fuente
Usando React y Axios , une el enlace proxy a la URL y agrega el encabezado como se muestra a continuación
https://cors-anywhere.herokuapp.com/
+Your API URL
Simplemente agregando el enlace Proxy funcionará, pero también puede arrojar un error para Sin acceso nuevamente. Por lo tanto, es mejor agregar encabezado como se muestra a continuación.
ADVERTENCIA: no debe usarse en producción
fuente
Si solo desea probar una aplicación de dominio cruzado en la que el navegador bloquea su solicitud, puede simplemente abrir su navegador en modo inseguro y probar su aplicación sin cambiar su código y sin hacer que su código sea inseguro. Desde MAC OS puede hacer esto desde la línea de terminal:
fuente
Si está utilizando PHP, intente agregar el siguiente código al comienzo del archivo php:
Si está utilizando localhost, intente esto:
Si está utilizando dominios externos como el servidor, intente esto:
fuente
yo trabajo con express 4 y node 7.4 y angular, tuve el mismo problema, lo ayudo a:
a) lado del servidor: en el archivo app.js doy encabezados a todas las respuestas como:
Esto debe tener antes de todo el enrutador .
Vi muchos encabezados añadidos:
pero no necesito eso,
b) del lado del cliente: en send ajax necesitas agregar: "withCredentials: true", como:
buena suerte.
fuente
res.header('Access-Control-Allow-Origin', req.headers.origin);
es lo mismo queres.header('Access-Control-Allow-Origin', '*');
Para compartir el origen cruzado, configure el encabezado:
'Access-Control-Allow-Origin':'*';
Php:
header('Access-Control-Allow-Origin':'*');
Nodo:
app.use('Access-Control-Allow-Origin':'*');
Esto permitirá compartir contenido para diferentes dominios.
fuente
En Python, he estado usando la
Flask-CORS
biblioteca con gran éxito. Hace que tratar con CORS sea súper fácil e indoloro. Agregué un código de la documentación de la biblioteca a continuación.Instalando:
Ejemplo simple que permite CORS para todos los dominios en todas las rutas:
Para ejemplos más específicos ver la documentación. He usado el sencillo ejemplo anterior para solucionar el problema de CORS en una aplicación iónica que estoy creando que tiene que acceder a un servidor de matraz separado.
fuente
Desde mi propia experiencia, es difícil encontrar una explicación simple de por qué CORS es incluso una preocupación.
Una vez que comprenda por qué está allí, los encabezados y la discusión se vuelven mucho más claros. Lo intentaré en unas pocas líneas.
Se trata de cookies. Las cookies se almacenan en un cliente por su dominio.
Punto clave: cuando un cliente realiza una solicitud al servidor, enviará las cookies almacenadas en el dominio en el que se encuentra el cliente.
Si otro cliente realiza una solicitud de origen cruzado a un servidor, esas cookies se envían, como antes. Ruh Roh.
Dado que las cookies se validan como se esperaba, el servidor autorizará la respuesta.
Yikes
Entonces, algunas preguntas y respuestas se hacen aparentes:
fuente
Simplemente pegue el siguiente código en su archivo web.config.
Notó que, debe pegar el siguiente código en la
<system.webServer>
etiquetafuente
Para más información, visite aquí ...
fuente
Nginx y Appache
Además de la respuesta de apsillers, me gustaría agregar un gráfico wiki que muestre cuándo la solicitud es simple o no (y las opciones de solicitud previa al vuelo se envían o no)
Para una solicitud simple (por ejemplo, imágenes de hotlinking ), no necesita cambiar los archivos de configuración de su servidor, pero puede agregar encabezados en la aplicación (alojada en el servidor, por ejemplo, en php) como Melvin Guerrero menciona en su respuesta , pero recuerde : si agrega completo los encabezados cors en su servidor (config) y al mismo tiempo permite cors simples en la aplicación (por ejemplo, php), esto no funcionará en absoluto.
Y aquí hay configuraciones para dos servidores populares
encienda CORS en Nginx (
nginx.conf
archivo)Mostrar fragmento de código
encienda CORS en Appache (
.htaccess
archivo)Mostrar fragmento de código
fuente