Aparentemente, he entendido completamente mal su semántica. Pensé en algo como esto:
http://siteA - el origen .http://siteB , lo que pensé que significaba que MyCode.js podía hacer referencias de origen cruzado al sitio B.http://siteB , lo que debería estar bien, a pesar de ser solicitudes de origen cruzado.Bueno, estoy equivocado. No funciona así en absoluto. Entonces, he leído Intercambio de recursos de origen cruzado e intenté leer Intercambio 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 tanto del sitio A como 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.
Para .NET Core 3.1 API con Angular
Startup.cs : Agregar CORS
//SERVICES public void ConfigureServices(IServiceCollection services){ //CORS (Cross Origin Resource Sharing) //===================================== services.AddCors(); } //MIDDLEWARES public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); //ORDER: CORS -> Authentication -> Authorization) //CORS (Cross Origin Resource Sharing) //===================================== app.UseCors(x=>x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200")); app.UseHttpsRedirection(); } }Controlador : habilitar CORS para controlador autorizado
//Authorize all methods inside this controller [Authorize] [EnableCors()] public class UsersController : ControllerBase { //ActionMethods }No puedo configurarlo en el servidor back-end pero con estas extensiones en los navegadores funcionan para mí:
Para Firefox:Cors en todas partes
Para Google Chrome: Permitir CORS: Acceso-Control-Permitir-Origin
Nota: CORS funciona para mí con esta configuración:
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á ahí, los encabezados y la discusión se vuelven mucho más claros. Le daré una oportunidad en unas pocas líneas.
Se trata de galletas. Las cookies se almacenan en un cliente por su dominio.
Una historia de ejemplo: en su computadora, hay una cookie para
yourbank.com. Tal vez su sesión está ahí.
Punto clave: cuando un cliente realiza una solicitud al servidor, enviará las cookies almacenadas en el dominio para esa solicitud.
Ha iniciado sesión en su navegador en
yourbank.com. Usted solicita ver todas sus cuentas y se envían cookies parayourbank.com.yourbank.comrecibe la pila de cookies y envía su respuesta (sus cuentas).
Si otro cliente realiza una solicitud de origen cruzado a un servidor, esas cookies se envían, igual que antes. Ruh roh.
Usted navega a
malicious.com. Malicious hace un montón de solicitudes a diferentes bancos, incluidoyourbank.com.
Dado que las cookies se validan como se esperaba, el servidor autorizará la respuesta.
Esas cookies se recopilan y envían, y ahora,
malicious.comtiene una respuesta deyourbank.
¡Ay!
Así que ahora, algunas preguntas y respuestas se hacen evidentes:
SOLO SOLUCIÓN TEMPORAL para Pruebas:
Quién no puede controlar el backend para Options 405 Method Not Allowed .
Solución alternativa para el navegador Chrome.
ejecutar en línea de comando:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="path_to_profile"
Ejemplo:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\Users\vital\AppData\Local\Google\Chrome\User Data\Profile 2"
Usando React y Axios , únase al enlace proxy a la URL y agregue el encabezado como se muestra a continuación
https://cors-anywhere.herokuapp.com/ + Your API URL
Solo agregando el enlace Proxy funcionará, pero también puede arrojar un error de Sin acceso nuevamente. Por lo tanto, es mejor agregar un encabezado como se muestra a continuación.
axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}}) .then(response => console.log(response:data); }Esta es solo una solución rápida, si tiene problemas con la razón por la que no puede obtener una respuesta, PUEDE usar esto. Pero, de nuevo, no es la mejor respuesta para la producción.
Obtuve varios votos negativos y tiene mucho sentido, debería haber agregado la advertencia hace mucho tiempo.
En Python, he estado usando la biblioteca Flask-CORS con gran éxito. Hace que lidiar con CORS sea súper fácil e indoloro. Agregué un código de la documentación de la biblioteca a continuación.
Instalación:
$ pip install -U flask-corsEjemplo simple que permite CORS para todos los dominios en todas las rutas:
from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) @app.route("/") def helloWorld(): return "Hello, cross-origin-world!"Para ejemplos más específicos vea la documentación. He usado el ejemplo simple anterior para solucionar el problema de CORS en una aplicación iónica que estoy creando y que tiene que acceder a un servidor de matraz separado.
Cada vez que empiezo a pensar en CORS, mi intuición sobre qué sitio aloja los encabezados es incorrecta, tal como lo describió en su pregunta. Para mí, ayuda pensar en el propósito de la política del mismo origen.
El propósito de la política del mismo origen es protegerlo de JavaScript malicioso en siteA.com que accede a información privada que eligió compartir solo con siteB.com. Sin la misma política de origen, el JavaScript escrito por los autores de siteA.com podría hacer que su navegador realice solicitudes a siteB.com, utilizando sus cookies de autenticación para siteB.com. De esta forma, 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 siteB.com, utilizando el encabezado Access-Control-Allow-Origin para enumerar otros dominios (siteA.com) en los que se confía para ejecutar JavaScript que puede interactuar con siteB.com.
Para comprender qué dominio debe servir los encabezados CORS, considere esto. Visita malicioso.com, que contiene código JavaScript que intenta realizar una solicitud entre dominios a mybank.com. Debería depender de mybank.com, no de malicioso.com, decidir si establece o no encabezados CORS que relajen la misma política de origen que permite que JavaScript de malicioso.com interactúe con él. Si malicous.com pudiera establecer sus propios encabezados CORS que permitieran 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. Cuando, de hecho, debería estar pensando en qué otros sitios JavaScript están tratando de interactuar con mi sitio y ¿debería usar CORS para permitirlos?
Simplemente pegue el siguiente código en su archivo web.config.
Observó que debe pegar el siguiente código en la etiqueta <system.webServer>
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol>El encabezado de respuesta Access-Control-Allow-Origin indica si la respuesta se puede compartir con el código de solicitud del origen dado.
Header type Response header Forbidden header name noUna respuesta que le dice al navegador que permita que el código de cualquier origen acceda a un recurso incluirá lo siguiente:
Access-Control-Allow-Origin: *Para más información, visite aquí ....
1. Un cliente descarga el código javascript MyCode.js desde http://sitioA - 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 a siteA y siteZ != siteA. (Usted no puede detener o interferir con esto.)
2. 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.
no. Significa que solo el sitio B puede realizar esta solicitud. Entonces, su solicitud de MyCode.js de siteZ recibe un error, 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á, eso permitirá que todos entren. O si el servidor siempre envía la cadena desde el encabezado Origen:... pero... por seguridad, si tienes miedo de los piratas informáticos , su servidor solo debe permitir orígenes en una lista corta, que pueden realizar esas solicitudes.
Luego, MyCode.js proviene del sitio A. Cuando realiza solicitudes al sitio B, todas son de origen cruzado, el navegador envía Origen: sitio A, 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 secuencia de comandos obtenga el resultado de esas solicitudes.
Para compartir orígenes cruzados, establezca 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.
Si está utilizando PHP, intente agregar el siguiente código al comienzo del archivo php:
Si está utilizando localhost, intente esto:
header("Access-Control-Allow-Origin: *");Si está utilizando dominios externos como un servidor, intente esto:
header("Access-Control-Allow-Origin: http://www.website.com");Trabajo con express 4 y node 7.4 y angular, tuve el mismo problema, ayúdame con esto:
a) lado del servidor: en el archivo app.js doy encabezados a todas las respuestas como:
app.use(function(req, res, next) { res.header('Access-Control-Allow-Origin', req.headers.origin); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); esto debe tener antes de todo enrutador .
Vi muchos encabezados agregados:
res.header("Access-Control-Allow-Headers","*"); res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); pero no necesito eso,
b) lado del cliente: en enviar ajax necesita agregar: "withCredentials: true", como:
$http({ method: 'POST', url: 'url, withCredentials: true, data : {} }).then(function(response){ // code }, function (response) { // code });Si solo desea probar una aplicación de dominio cruzado en la que el navegador bloquea su solicitud, puede abrir su navegador en modo inseguro y probar su aplicación sin cambiar su código y sin hacer que su código no sea seguro. Desde MAC OS puedes hacer esto desde la línea del terminal:
open -a Google\ Chrome --args --disable-web-security --user-data-dir