El origen no está permitido por Access-Control-Allow-Origin

337

Estoy haciendo un Ajax.requestservidor PHP remoto en una aplicación Sencha Touch 2 (envuelta en PhoneGap ).

La respuesta del servidor es la siguiente:

XMLHttpRequest no puede cargar http://nqatalog.negroesquisso.pt/login.php . El origen http://localhost:8888no está permitido por Access-Control-Allow-Origin.

¿Como puedo solucionar este problema?

Ricardo
fuente
19
durante el uso de jQuery, configuración dataType: 'jsonp',hace el truco
Amit
11
por cierto, esa no es la respuesta del servidor. Para ser precisos, ese error se emite en el lado del cliente.
matteo
2
El truco jsonp probablemente ya no funcione, para su información: stackoverflow.com/questions/12216208/…
drewww
77
Tenga en cuenta que, dado que acabo de perder medio día persiguiendo este error: si el script del lado del servidor falla con un error interno del servidor, el navegador puede interpretarlo como si la solicitud no estuviera permitida debido a esto Access-Control-Allow-Origine informarlo como un error.
troelskn
1
@troelskn Acabas de salvarme la vida. Estaba buscando un error de CORS desde hace 3 días, y fue simplemente un pequeño problema de configuración de Spring que causó un 500, que resolví en 5 minutos una vez que leí tu comentario y realmente lo busqué. ¡Gracias!
Alexis Dufrenoy

Respuestas:

378

Escribí un artículo sobre este tema hace un tiempo, Cross Domain AJAX .

La forma más fácil de manejar esto si tiene control del servidor que responde es agregar un encabezado de respuesta para:

Access-Control-Allow-Origin: *

Esto permitirá el dominio cruzado de Ajax . En PHP, querrás modificar la respuesta así:

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

Simplemente puede poner la Header set Access-Control-Allow-Origin *configuración en la configuración de Apache o en el archivo htaccess.

Cabe señalar que esto deshabilita efectivamente la protección CORS, que muy probablemente expone a sus usuarios a los ataques . Si no sabe que necesita usar un comodín específicamente, no debe usarlo y, en su lugar, debe incluir en la lista blanca su dominio específico:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>
Matt Mombrea
fuente
44
Me pondré en contacto con mi proveedor de servidores. Gracias
Ricardo
8
¿Hay problemas de seguridad con esto? Esta respuesta , por ejemplo, dice "JavaScript está limitado por la" misma política de origen "por razones de seguridad. Por ejemplo, un script malicioso no puede contactar a un servidor remoto y enviar datos confidenciales desde su sitio".
JohnK
44
Impresionante, acabo de poner esto en mi archivo de servidor node.js: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); Y funcionó. ¡Gracias!
vbullinger
25
JohnK, sí, el comodín permitirá que cualquier dominio envíe solicitudes a su host. Recomiendo reemplazar el asterisco con un dominio específico en el que ejecutará scripts.
Nick
77
Es interesante que pienses que el comodín ni siquiera debería sugerirse @jfrej. Todo depende de tu objetivo. Por ejemplo, la razón por la que usamos el comodín (y publicamos esta respuesta) fue porque estábamos creando un widget incrustado para que lo utilizara cualquier sitio.
Matt Mombrea
63

Si usted no tiene el control del servidor, sólo tiene que añadir este argumento a su lanzador Chrome: --disable-web-security.

Tenga en cuenta que no usaría esto para la "navegación web" normal. Para referencia, vea esta publicación: Deshabilite la misma política de origen en Chrome .

Si usa Phonegap para compilar la aplicación y cargarla en el dispositivo, esto no será un problema.

Travis Webb
fuente
Gracias. Pero mi aplicación se ejecuta en dispositivos móviles, no puedo pasar argumentos a mi contenedor webview.
Ricardo
¿No pruebas primero tu aplicación en un navegador? ¿Cómo se depura?
Travis Webb
Sí, depuro en un navegador Chrome, pero la aplicación no se ejecutará en Chrome. Estará en webgap phoneview que no puedo controlar.
Ricardo
44
lea la respuesta: simplemente puede agregar este argumento a su iniciador de Chrome . No hay configuración para esto dentro de Chrome
Travis Webb
2
Por supuesto que es inseguro. El OP está pidiendo una forma de evitar las medidas de seguridad.
Travis Webb
42

Si está usando Apache simplemente agregue:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

en su configuración Esto hará que todas las respuestas de su servidor web sean accesibles desde cualquier otro sitio en Internet. Si tiene la intención de permitir que un servidor específico utilice los servicios en su host, puede reemplazarlos *con la URL del servidor de origen:

Header set Access-Control-Allow-Origin: http://my.origin.host
Reza S
fuente
3
Y no olvide cargar el módulo: encabezados a2enmod
Walery Strauch
¿Cómo cargar el módulo: encabezados a2enmod?
Ayesha
18

Si tiene una aplicación ASP.NET / ASP.NET MVC , puede incluir este encabezado a través del archivo Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>
C. Augusto Proiete
fuente
2
.NET MVC People, ¡MIRE aquí! De hecho, voy a escribir una solución y señalar esta respuesta en mi blog para que la gente pueda encontrarla más fácilmente. Nada peor que tratar de superar un obstáculo .NET / MVC y encontrar nada más que soluciones PHP / jQuery. Gracias @ Caio-Proiete
ottoflux
1
¿Cómo es que esto no funciona para mí? Estoy usando Chrome e intento acceder a la página de finanzas de Yahoo desde mi host local.
newman
1
gracias funcionó para mí He agregado en el proyecto de código del lado del servidor (web.config).
ethem
15

Esta fue la primera pregunta / respuesta que surgió cuando traté de resolver el mismo problema usando ASP.NET MVC como fuente de mis datos. Me doy cuenta de que esto no resuelve la pregunta de PHP , pero está lo suficientemente relacionado como para ser valioso.

Estoy usando ASP.NET MVC. La publicación de blog de Greg Brant funcionó para mí. En última instancia, crea un atributo [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]que puede agregar a las acciones del controlador.

Por ejemplo:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

Y luego usarlo con:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}
badMonkey
fuente
1
WebApi 2 tiene esto incorporado ahora. asp.net/web-api/overview/security/…
Matt Frear
10

Como Matt Mombrea es correcto para el lado del servidor, puede encontrarse con otro problema que es el rechazo de la lista blanca.

Tienes que configurar tu phonegap.plist. (Estoy usando una versión anterior de phonegap)

Para cordova, puede haber algunos cambios en el nombre y el directorio. Pero los pasos deberían ser casi los mismos.

Primero seleccione Archivos de soporte> PhoneGap.plist

ingrese la descripción de la imagen aquí

luego en "ExternalHosts"

Agregue una entrada, con un valor de quizás " http://nqatalog.negroesquisso.pt " Estoy usando * solo para propósitos de depuración.

ingrese la descripción de la imagen aquí

steve0hh
fuente
8

Esto puede ser útil para cualquier persona que necesite una excepción para las versiones 'www' y 'no www' de un referente:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }
lewsid
fuente
Me señaló en la dirección correcta para resolver el error ACAO con azul. Si bien había agregado el nombre de host permitido de googledrive. La URL utilizada debe ser googledrive NO googledrive
Kildareflare
7

Te daré una solución simple para este. En mi caso no tengo acceso a un servidor. En ese caso, puede cambiar la política de seguridad en su navegador Google Chrome para permitir Access-Control-Allow-Origin. Esto es muy simple:

  1. Crear un acceso directo al navegador Chrome
  2. Haga clic con el botón derecho en el icono de acceso directo -> Propiedades -> Acceso directo -> Destino

Pasta simple en "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

La ubicación puede diferir. Ahora abra Chrome haciendo clic en ese acceso directo.

Dibish
fuente
7

Me he encontrado con esto varias veces cuando trabajo con varias API. A menudo, una solución rápida es agregar "& callback =?" hasta el final de una cuerda. A veces, el signo "y" tiene que ser un código de caracteres y, a veces, un "?": "? Callback =?" (vea el uso de Forecast.io API con jQuery )

Francis Baptiste
fuente
6

Si estás escribiendo una extensión de Chrome y obtiene este error, a continuación, asegúrese de haber agregado la URL base del API a su manifest.json's bloque de permisos , ejemplo:

"permissions": [
    "https://itunes.apple.com/"
]
itzg
fuente
6

Esto se debe a la política del mismo origen . Ver más en Mozilla Developer Network o Wikipedia .

Básicamente, en su ejemplo, necesita cargar la http://nqatalog.negroesquisso.pt/login.phppágina solo desde nqatalog.negroesquisso.pt, no localhost.

antyrat
fuente
1
Pero necesito cargar el servicio web desde un dispositivo móvil, ¿me saltaría esto?
Ricardo
Bueno, debes hacer algunos cambios en el lado del servidor o usar JSONP en.wikipedia.org/wiki/JSONP
antyrat
6

si está bajo Apache, simplemente agregue un archivo .htaccess a su directorio con este contenido:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *
Vero O
fuente
5

En Ruby on Rails , puedes hacer en un controlador:

headers['Access-Control-Allow-Origin'] = '*'
fuzzyalej
fuente
¿en qué controlador pones esto si es una llamada ajax? ¿Puedo ver más contexto de código?
rigdonmr
5

Puede hacer que funcione sin modificar el servidor haciendo que el filtro incluya el encabezado Access-Control-Allow-Origin: *en las respuestas de las OPCIONES HTTP.

En Chrome, usa esta extensión . Si estás en Mozilla revisa esta respuesta .

forzagreen
fuente
5

Si obtiene esto en Angular.js, asegúrese de escapar de su número de puerto de esta manera:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Vea aquí para más información al respecto.

Mario
fuente
4

También tenemos el mismo problema con la aplicación phonegap probada en Chrome. Una máquina de Windows que utilizamos debajo del archivo por lotes todos los días antes de abrir Chrome. Recuerde que antes de ejecutar esto, debe limpiar todas las instancias de Chrome desde el administrador de tareas o puede seleccionar Chrome para que no se ejecute en segundo plano.

LOTE: (use cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security
abksharma
fuente
1

En Ruby Sinatra

response['Access-Control-Allow-Origin'] = '*' 

para todos o

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 
Mikhail Chuprynski
fuente
0

Cuando reciba la solicitud, puede

var origin = (req.headers.origin || "*");

que cuando tienes que responder ve con algo así:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
Alessandro Annini
fuente