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

184

He creado un pequeño archivo xslt para crear una salida html llamada weather.xsl con el siguiente código:

<!-- DWXMLSource="http://weather.yahooapis.com/forecastrss?w=38325&u=c" -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="yweather"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <img src="{/*/*/item/yweather:condition/@text}.jpg"/>
</xsl:template>
</xsl:stylesheet>

Quiero cargar la salida html en un div en un archivo html que estoy tratando de hacer usando jQuery de la siguiente manera:

<div id="result">
<script type="text/javascript">
$('#result').load('weather.xsl');
</script>
</div>

Pero recibo el siguiente error: Access null no está permitido por Access-Control-Allow-Origin.

He leído sobre agregar un encabezado al xslt, pero no estoy seguro de cómo hacerlo, por lo que agradecería cualquier ayuda, y si la carga en la salida html no se puede hacer de esta manera, entonces se aconseja cómo más hacerlo sería genial.

dudledok
fuente
¿Es esa tu llamada real load ? ¿No hay camino en absoluto?
TJ Crowder

Respuestas:

227

Origin nulles el sistema de archivos local, por lo que sugiere que está cargando la página HTML que realiza la loadllamada a través de una file:///URL (por ejemplo, simplemente haciendo doble clic en un explorador de archivos local o similar). Los diferentes navegadores adoptan diferentes enfoques para aplicar la Política del mismo origen a los archivos locales.

Supongo que estás viendo esto usando Chrome. Las reglas de Chrome para aplicar el SOP a los archivos locales son muy estrictas, no permite incluso cargar archivos desde el mismo directorio que el documento. También lo hace Opera. Algunos otros navegadores, como Firefox, permiten un acceso limitado a los archivos locales. Pero básicamente, usar ajax con recursos locales no va a funcionar entre navegadores.

Si solo está probando algo localmente que realmente implementará en la web, en lugar de usar archivos locales, instale un servidor web simple y pruebe a través de http://URL. Eso le da una imagen de seguridad mucho más precisa.

TJ Crowder
fuente
1
Después de cargarlo, ya no obtengo Origin nulo, pero sigo recibiendo "no permitido por Access-Control-Allow-Origin".
dudledok
3
Si el recurso que está cargando es como lo ha mostrado ( $('#result').load('weather.xsl');), eso no debería suceder, porque la solicitud está claramente en el mismo origen. Si está intentando cargar desde otro lugar (p. Ej. $('#result').load('http://somewhere.else/weather.xsl');), Entonces se encuentra con el SOP nuevamente, pero de una manera diferente. Las solicitudes de Ajax están restringidas al mismo origen (vea el enlace en la respuesta), o si está utilizando un navegador habilitado para CORS y el servidor admite COR, el servidor puede elegir si desea permitir la solicitud de origen cruzado.
TJ Crowder
Cambié la url de carga. Cambiarlo de nuevo al de la pregunta hace que se cargue bien. Gracias por la ayuda
dudledok
2
¿Cuál es la forma más simple y rápida de configurar un servidor web simple? ¿IIS sería la forma más simple aquí?
Ciaran Gallagher
13
@CiaranG Corrí python -m SimpleHTTPServerdesde una línea de comando y luego fui a localhost: 8000, funcionó para mí. Python viene preinstalado con Mac OS X; Es posible que deba instalarlo si usa otro sistema operativo.
Dave Liepmann
216

Chrome y Safari tienen una restricción sobre el uso de ajax con recursos locales. Es por eso que arroja un error como

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

Solución: use firefox o cargue sus datos en un servidor temporal. Si aún desea usar Chrome, comience con la siguiente opción;

--allow-file-access-from-files

Más información sobre cómo agregar el parámetro anterior a su Chrome: haga clic derecho en el icono de Chrome en su barra de tareas, haga clic con el botón derecho en Google Chrome en la ventana emergente y haga clic en propiedades y agregue el parámetro anterior dentro del cuadro de texto Destino en la pestaña Atajo. Le gustará como a continuación;

C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

Espero que esto ayude!

Tanque Gokhan
fuente
19
En Mac OS X, puede iniciar Chrome con esta opción abriendo un terminal y escribiendo: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files & Tenga en cuenta que el final & es solo para que pueda continuar usando el Terminal y no es obligatorio. NOTA: Si cierra el terminal, cerrará la ventana de Chrome.
Bruno Bernardino
3
Hizo todo eso y cerró y abrió. Todavía no funciona (Chrome 27.0.1453.116 m en XP)
mplungjan
No estoy siendo capaz de añadir este parámetro en Windows 8 ..., cualquiera que sepa cómo hacerlo ...?
Morty
Yo estoy corriendo desde un servidor web. ¿Que demonios? ¿Cómo puedo averiguar dónde está cargando archivos locales?
Andy
Cuando intento agregar --allow-file-access-from-files a la ruta de destino, recibo un mensaje "... no válido", ¿esta solución sigue siendo válida?
alex
48

Solo quería agregar que la respuesta "ejecutar un servidor web" parece bastante desalentadora, pero si tiene Python en su sistema (instalado de forma predeterminada al menos en MacOS y cualquier distribución de Linux) es tan fácil como:

python -m http.server  # with python3

o

python -m SimpleHTTPServer  # with python2

Entonces, si tiene su archivo html myfile.htmlen una carpeta, digamos mydir, todo lo que tiene que hacer es:

cd /path/to/mydir
python -m http.server  # or the python2 alternative above

Luego apunte su navegador a:

http://localhost:8000/myfile.html

Y ya está! Funciona en todos los navegadores , sin deshabilitar la seguridad web, permitir archivos locales o incluso reiniciar el navegador con opciones de línea de comandos.

gozzilli
fuente
2
Python 3 equivalente en Windows es: python -m http.server [<portNo>]
Aragorn
Python 3: python3 -m http.server
João Nunes
Python 2 en Linux, eligiendo el puerto 8080 (o cualquier otro que desee):python -m SimpleHTTPServer 8080
Rodrigo
2

Me gustaría agregar humildemente que de acuerdo con esta fuente SO: https://stackoverflow.com/a/14671362/1743693 , este tipo de problema ahora se resuelve parcialmente simplemente usando la siguiente instrucción jQuery:

<script> 
    $.support.cors = true;
</script>

Lo probé en IE10.0.9200, y funcionó de inmediato (usando jquery-1.9.0.js).

En Chrome 28.0.1500.95: esta instrucción no funciona (esto sucede todo cuando David se queja en los comentarios en el enlace de arriba)

Ejecutar Chrome con --allow-file-access-from-files no funcionó para mí (como afirma Maistora anteriormente)

Orberkov
fuente
2

Agregando un poco para usar la solución de Gokhan para usar:

--allow-file-access-from-files

Ahora solo necesita agregar el texto de arriba en el Texto de destino seguido de un espacio. asegúrese de cerrar todas las instancias del navegador Chrome después de agregar la propiedad anterior. Ahora reinicie Chrome con el icono donde agregó esta propiedad. Debería funcionar para todos.

saurabh
fuente
El parámetro ya fue presentado por Ghokan Tank y descubrir cómo hacer que el navegador siempre comience con este parámetro no es parte de la pregunta. Además, no puede asumir que todos usan Microsoft Windows.
jnns
0

Estaba buscando una solución para hacer una solicitud XHR a un servidor desde un archivo html local y encontré una solución usando Chrome y PHP. (sin Jquery)

Javascripts:

var x = new XMLHttpRequest(); 
if(x) x.onreadystatechange=function(){ 
    if (x.readyState === 4 && x.status===200){
        console.log(x.responseText); //Success
    }else{ 
        console.log(x); //Failed
    }
};
x.open(GET, 'http://example.com/', true);
x.withCredentials = true;
x.send();

El encabezado de solicitud de mi Chrome Origin: null

Mi encabezado de respuesta PHP (tenga en cuenta que 'nulo' es una cadena ). HTTP_REFERER permite el origen cruzado de un servidor remoto a otro.

header('Access-Control-Allow-Origin: '.(trim($_SERVER['HTTP_REFERER'],'/')?:'null'),true);
header('Access-Control-Allow-Credentials:true',true);

Pude conectarme con éxito a mi servidor. Puede ignorar los encabezados de Credenciales, pero esto funciona para mí con ApacheAuthType Basic habilitado

Probé la compatibilidad con FF y Opera, funciona en muchos casos como:

Desde una IP LAN de VM (192.168.0.x) de regreso a la IP WAN (pública) de
VM : puerto Desde una IP LAN de VM de regreso a un nombre de dominio de servidor remoto.
Desde un archivo .HTML local a la IP LAN de VM y / o IP WAN de VM: puerto,
Desde un archivo .HTML local a un nombre de dominio de servidor remoto.
Y así.

Louis Loudog Trottier
fuente
0

Puede cargar un archivo Javascript local (en el árbol debajo de su file:/página de origen) usando la etiqueta de origen:

<script src="my_data.js"></script>

Si codifica su entrada en Javascript, como en este caso:

mydata.js :

$xsl_text = "<xsl:stylesheet version="1.0" + ....

(esto es más fácil para json), entonces tiene sus 'datos' en una variable global Javascript para usar como desee.

Rico
fuente