L'origine nulle n'est pas autorisée par Access-Control-Allow-Origin

184

J'ai créé un petit fichier xslt pour créer une sortie html appelée weather.xsl avec le code suivant:

<!-- 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>

Je veux charger la sortie html dans un div dans un fichier html que j'essaie de faire en utilisant jQuery comme suit:

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

Mais j'obtiens l'erreur suivante: Origin null n'est pas autorisé par Access-Control-Allow-Origin.

J'ai lu sur l'ajout d'un en-tête au xslt, mais je ne sais pas comment faire cela, donc toute aide serait appréciée, et si le chargement dans la sortie html ne peut pas être fait de cette façon, alors des conseils sur la façon dont ce serait formidable.

Dudledok
la source
Est-ce votre véritable load appel? Il n'y a pas de chemin du tout?
TJ Crowder

Réponses:

227

Origin nullest le système de fichiers local, ce qui suggère que vous chargez la page HTML qui effectue l' loadappel via une file:///URL (par exemple, double-cliquez dessus dans un navigateur de fichiers local ou similaire). Différents navigateurs adoptent différentes approches pour appliquer la même politique d'origine aux fichiers locaux.

Je suppose que vous voyez cela avec Chrome. Les règles de Chrome pour appliquer le SOP aux fichiers locaux sont très strictes, il interdit même le chargement de fichiers à partir du même répertoire que le document. Il en va de même pour Opera. Certains autres navigateurs, tels que Firefox, autorisent un accès limité aux fichiers locaux. Mais fondamentalement, l'utilisation d'ajax avec des ressources locales ne fonctionnera pas entre les navigateurs.

Si vous testez simplement quelque chose localement que vous déploierez vraiment sur le Web, plutôt que d'utiliser des fichiers locaux, installez un simple serveur Web et testez http://plutôt via des URL. Cela vous donne une image de sécurité beaucoup plus précise.

TJ Crowder
la source
1
Après l'avoir téléchargé, je n'obtiens plus la valeur Origin null, mais je reçois toujours "non autorisé par Access-Control-Allow-Origin".
dudledok
3
Si la ressource que vous chargez est comme vous l'avez montré ( $('#result').load('weather.xsl');), cela ne devrait pas se produire, car la demande est clairement à la même origine. Si vous essayez de charger depuis un autre endroit (par exemple, $('#result').load('http://somewhere.else/weather.xsl');), alors vous vous retrouvez dans le SOP, mais d'une manière différente. Ajax demandes sont limitées à la même origine (voir le lien en réponse), ou si vous utilisez un CORS navigateur -Enabled et le serveur prend en charge SCRO le serveur peut choisir d'autoriser ou non la demande croisée d'origine.
TJ Crowder du
J'ai changé l'URL de chargement. Le ramener à celui de la question rend le chargement correct. Merci pour l'aide
dudledok
2
Quel est le moyen le plus simple et le plus rapide de configurer un serveur Web simple? IIS serait-il le moyen le plus simple ici?
Ciaran Gallagher
13
@CiaranG J'ai couru à python -m SimpleHTTPServerpartir d'une ligne de commande, puis je suis allé sur localhost: 8000, j'ai travaillé pour moi. Python est préinstallé avec Mac OS X; vous devrez peut-être installer si vous utilisez un autre système d'exploitation.
Dave Liepmann
216

Chrome et Safari ont une restriction sur l'utilisation d'ajax avec des ressources locales. C'est pourquoi il lance une erreur comme

L'origine nulle n'est pas autorisée par Access-Control-Allow-Origin.

Solution: utilisez Firefox ou téléchargez vos données sur un serveur temporaire. Si vous souhaitez toujours utiliser Chrome, démarrez-le avec l'option ci-dessous;

--allow-file-access-from-files

Plus d'informations comment ajouter le paramètre ci-dessus à votre Chrome: Faites un clic droit sur l'icône Chrome dans votre barre des tâches, faites un clic droit sur Google Chrome dans la fenêtre pop-up et cliquez sur Propriétés et ajoutez le paramètre ci-dessus dans la zone de texte Cible sous l'onglet Raccourci. Il aimera comme ci-dessous;

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

J'espère que cela aidera!

Débardeur Gokhan
la source
19
Sous Mac OS X, vous pouvez démarrer Chrome avec cette option en ouvrant un terminal et en tapant: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files & Notez le & final juste pour que vous puissiez continuer à utiliser le terminal et ce n'est pas obligatoire. REMARQUE: si vous fermez le terminal, la fenêtre Chrome sera fermée.
Bruno Bernardino
3
J'ai fait tout cela et fermé et ouvert. toujours pas aller (Chrome 27.0.1453.116 m sur XP)
mplungjan
Je ne peux pas ajouter ce paramètre sous Windows 8 ..., quelqu'un qui sait comment le faire? ...
Morty
Je suis en cours d' exécution à partir d' un serveur Web. Que diable? Comment puis-je savoir où il charge les fichiers locaux?
Andy
Lorsque j'essaye d'ajouter --allow-file-access-from-files au chemin cible, j'obtiens un message ".... invalid", la solution htis est-elle toujours valide?
alex le
48

Je voulais juste ajouter que la réponse «exécuter un serveur Web» semble assez intimidante, mais si vous avez python sur votre système (installé par défaut au moins sur MacOS et toute distribution Linux), c'est aussi simple que:

python -m http.server  # with python3

ou

python -m SimpleHTTPServer  # with python2

Donc, si vous avez votre fichier html myfile.htmldans un dossier, disons mydir, tout ce que vous avez à faire est:

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

Puis pointez votre navigateur sur:

http://localhost:8000/myfile.html

Et vous avez terminé! Fonctionne sur tous les navigateurs , sans désactiver la sécurité Web, autoriser les fichiers locaux ou même redémarrer le navigateur avec des options de ligne de commande.

gozzilli
la source
2
l'équivalent de python 3 sur Windows est: python -m http.server [<portNo>]
Aragorn
Python 3: python3 -m http.server
João Nunes
Python 2 sur Linux, en choisissant le port 8080 (ou tout autre que vous voulez):python -m SimpleHTTPServer 8080
Rodrigo
2

Je voudrais humblement ajouter que selon cette source SO: https://stackoverflow.com/a/14671362/1743693 , ce genre de problème est maintenant partiellement résolu simplement en utilisant l'instruction jQuery suivante:

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

Je l'ai essayé sur IE10.0.9200, et cela a fonctionné immédiatement (en utilisant jquery-1.9.0.js).

Sur chrome 28.0.1500.95 - cette instruction ne fonctionne pas (cela se produit partout comme David se plaint dans les commentaires sur le lien ci-dessus)

L'exécution de chrome avec --allow-file-access-from-files ne fonctionnait pas pour moi (comme le prétend Maistora ci-dessus)

Orberkov
la source
2

Ajout d'un peu pour utiliser la solution de Gokhan pour utiliser:

--allow-file-access-from-files

Il vous suffit maintenant d'ajouter le texte ci-dessus dans le texte cible suivi d'un espace. assurez-vous de fermer toutes les instances du navigateur Chrome après avoir ajouté la propriété ci-dessus. Redémarrez maintenant Chrome par l'icône où vous avez ajouté cette propriété. Cela devrait fonctionner pour tous.

saurabh
la source
Le paramètre a déjà été présenté par Ghokan Tank et savoir comment toujours démarrer le Browser avec ce paramètre ne fait pas partie de la question. En outre, vous ne pouvez pas supposer que tout le monde utilise Microsoft Windows.
jnns
0

Je cherchais une solution pour faire une requête XHR à un serveur à partir d'un fichier html local et j'ai trouvé une solution utilisant Chrome et PHP. (pas de 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();

En-tête de demande de mon Chrome Origin: null

Mon en-tête de réponse PHP (notez que «null» est une chaîne ). HTTP_REFERER autorise l'origine croisée d'un serveur distant à un autre.

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

J'ai pu me connecter avec succès à mon serveur. Vous pouvez ignorer les en-têtes Credentials, mais cela fonctionne pour moi avec Apache AuthType Basicactivé

J'ai testé la compatibilité avec FF et Opera, cela fonctionne dans de nombreux cas tels que:

Depuis une IP LAN VM (192.168.0.x) vers l'IP WAN (publique) de
VM : port Depuis une IP LAN VM vers un nom de domaine de serveur distant.
À partir d'un fichier .HTML local vers l'adresse IP LAN de la VM et / ou l'IP WAN de la VM: port,
D'un fichier .HTML local vers un nom de domaine de serveur distant.
Etc.

Louis Loudog Trottier
la source
0

Vous pouvez charger un fichier Javascript local (dans l'arborescence sous votre file:/page source) en utilisant la balise source:

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

Si vous encodez votre entrée en Javascript, comme dans ce cas:

mydata.js :

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

(c'est plus facile pour json) alors vous avez vos 'données' dans une variable globale Javascript à utiliser comme vous le souhaitez.

Riches
la source