No hay encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado. Por lo tanto, el origen '...' no tiene acceso permitido

135

Estoy usando .htaccess para reescribir las URL y utilicé la etiqueta base html para que funcione.

Ahora, cuando trato de hacer una solicitud ajax, aparece el siguiente error:

XMLHttpRequest no se puede cargar http://www.example.com/login.php. No hay encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado. Origen ' http://example.com', por lo tanto, no se permite el acceso.

Th3lmuu90
fuente
1
No importa ... está funcionando ahora, ni siquiera sé cuál fue el error: S
Th3lmuu90
8
Aunque sutil, http://wordicious.comes un dominio diferente que http://www.wordicious.com/, por lo tanto, el error. Por cierto, si está funcionando ahora y regresó por sí solo, probablemente debería eliminar la pregunta.
acdcjunior
@acdcjunior Ese parece ser el error, que es una observación astuta de su parte. Si publicas eso como respuesta, lo votaría.
Waleed Khan
55
¡Es bueno que la pregunta no haya sido eliminada, o no la habría visto hoy!
agua helada

Respuestas:

170

Uso addHeaderEn lugar de usar el setHeadermétodo,

response.addHeader("Access-Control-Allow-Origin", "*");

*en la línea de arriba lo permitirá access to all domains.


Por permitir access to specific domain only:

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

Mira esto blog post.

Jay Patel
fuente
44
muestra un encabezado no definido. ¿Puedes por favor explicarlo?
Vaisakh Pc
9
¿Dónde pongo estas líneas?
DaveWalley
14
¿Dónde se debe agregar esto?
Alex
1
Esa publicación de blog está hablando de Node.js y express. No es javascript del lado del cliente. ¿Alguien puede confirmar si esto funciona?
Sam Eaton el
1
No creo que esta configuración se pueda hacer solo en el lado del cliente. En cuanto a dónde colocarla, sería en el código del lado del servidor (presumiblemente cuando se genera una respuesta a una solicitud)
Chirag Ravindra
145

Por qué se genera el error:

El código JavaScript está limitado por la política del mismo origen , lo que significa que, desde una página en www.example.com, solo puede realizar solicitudes (AJAX) a servicios ubicados exactamente en el mismo dominio, en ese caso, exactamente www.example.com( no example.com - sin el www- o whatever.example.com).

En su caso, su código Ajax está tratando de llegar a un servicio http://wordicious.comdesde una página ubicada en http://www.wordicious.com.

Aunque muy similares, son no el mismo dominio. Y cuando no están en el mismo dominio, la solicitud solo tendrá éxito si la respuesta del objetivo contiene un Access-Control-Allow-Originencabezado.

Como su página / servicio en http://wordicious.comnunca se configuró para presentar dicho encabezado, se muestra ese mensaje de error.

Solución:

Como se dijo, los dominios de origen (donde está la página con JavaScript) y el destino (donde está tratando de alcanzar JavaScript) deben ser exactamente los mismos.

Tu caso parece un error tipográfico. Parece http://wordicious.comy en http://www.wordicious.comrealidad son el mismo servidor / dominio. Así que para fijar, escriba el destino y el origen por igual: hacerte Ajax páginas de solicitud de código / servicios que http://www.wordicious.comnohttp://wordicious.com . (Quizás coloque la URL de destino relativamente, como '/login.php', sin el dominio).



En una nota más general:

Si el problema no es un error tipográfico como el de esta pregunta, la solución sería agregarlo Access-Control-Allow-Original dominio de destino . Agregarlo depende, por supuesto, del servidor / idioma detrás de esa dirección. A veces, una variable de configuración en la herramienta hará el truco. Otras veces tendrá que agregar los encabezados a través del código usted mismo.

acdcjunior
fuente
62

Para el servidor .NET puede configurar esto en web.config como se muestra a continuación

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

Por ejemplo, si el dominio del servidor es http://live.makemypublication.com y el cliente es http://www.makemypublication.com , configúrelo en el servidor web.config como se muestra a continuación.

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>
Naga
fuente
Una solución aún mejor. Gracias
ANJYR - KODEXPRESSION
Muchas gracias. Me salvaste todo el día.
Prateek Gupta
Trabajando incluso después de 2 años: p
Desarrolladores
1
@SyedAliTaqi la pregunta es php, por eso la respuesta está subestimada. sin embargo funcionó para mí también :)
Ahmad Th
22

Si recibe este mensaje de error del navegador:

No hay encabezado 'Access-Control-Allow-Origin' presente en el recurso solicitado. Por lo tanto, el origen '...' no tiene acceso permitido

cuando intente hacer una solicitud Ajax POST / GET a un servidor remoto que está fuera de su control, olvide esta solución simple:

<?php header('Access-Control-Allow-Origin: *'); ?>

Lo que realmente necesita hacer, especialmente si solo usa JavaScript para hacer la solicitud de Ajax, es un proxy interno que tome su consulta y la envíe al servidor remoto.

Primero en su JavaScript, haga una llamada Ajax a su propio servidor, algo como:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Luego, cree un archivo PHP simple llamado proxy.php para envolver sus datos POST y agregarlos al servidor de URL remoto como parámetros. Te doy un ejemplo de cómo evito este problema con la API de búsqueda de hoteles de Expedia:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

Haciendo:

 echo json_encode(file_get_contents($url));

Simplemente está haciendo la misma consulta pero en el lado del servidor y después de eso, debería funcionar bien.

Nizar B.
fuente
@NizarBsb estás loco, lo sabes !!!!! : D, muchas gracias, tu respuesta me salvó la vida
Flash
10

Debe agregar esto al comienzo de su página php "login.php"

<?php header('Access-Control-Allow-Origin: *'); ?>
Sheriff sombrío
fuente
55
Definitivamente no es seguro.
devolución de llamada
7

debe colocar las claves / valores de encabezado en la respuesta del método de opciones. por ejemplo, si tiene un recurso en http://midominio.com/miresource , entonces, en el código de su servidor, escriba

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}
i-systech.com
fuente
3

Básicamente, modifique la respuesta del encabezado API agregando los siguientes parámetros adicionales.

Access-Control-Allow-Credentials: verdadero

Acceso-Control-Permitir-Origen: *

Pero esta no es una buena solución cuando se trata de la seguridad.

Piusha
fuente
3

La solución consiste en utilizar un proxy inverso que se ejecute en su host 'fuente' y que se reenvíe a su servidor de destino, como Fiddler:

Enlace aquí: http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

O un proxy inverso de Apache ...

hzrari
fuente
¿Se puede hacer esto en un nivel de configuración de Apache o Nginx para un dominio? por ejemplo, si un usuario accede a mysite.com (no www) y XHR solicita www.mysite.com, ¿puede una directiva htaccess o httpd.conf resolver esto?
codecowboy
Claro, su aplicación front-end debe comportarse como un proxy inverso. por ejemplo, para Apache, debe instalar mod_proxy y configurar sus reglas usando ProxyPassReverse ( httpd.apache.org/docs/current/mod/… ). Las mismas características parecen estar disponibles en Nginx también: wiki.nginx.org/LikeApache
hzrari
2

Agregue esto a su archivo PHP o controlador principal

header("Access-Control-Allow-Origin: http://localhost:9000");
Sam
fuente
para terminar - también necesitasheader("Access-Control-Allow-Credentials: true");
Adam
1

Resuelto con la siguiente entrada en httpd.conf

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]
Sandeep540
fuente
La única forma que funcionó para mí en Apache2, CentOS7, Larravel 5 y React
Shakiba Moshiri