Pochodzenie null jest niedozwolone przez Access-Control-Allow-Origin

184

Zrobiłem mały plik xslt, aby utworzyć wyjście html o nazwie weather.xsl z kodem w następujący sposób:

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

Chcę załadować dane wyjściowe HTML do pliku div w pliku HTML, który próbuję wykonać przy użyciu jQuery w następujący sposób:

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

Ale pojawia się następujący błąd: Początek null nie jest dozwolony przez Access-Control-Allow-Origin.

Czytałem o dodawaniu nagłówka do xslt, ale nie jestem pewien, jak to zrobić, więc każda pomoc byłaby mile widziana, a jeśli załadowanie pliku HTML nie może być wykonane w ten sposób, to porady dotyczące tego, jak inaczej robić to byłoby świetnie.

dudledok
źródło
Jest to, że rzeczywiste load wezwanie? W ogóle nie ma na to ścieżki?
TJ Crowder,

Odpowiedzi:

227

Pochodzenie nullto lokalny system plików, co sugeruje, że ładujesz stronę HTML wykonującą loadwywołanie za pomocą file:///adresu URL (np. Wystarczy dwukrotnie kliknąć ją w lokalnej przeglądarce plików lub podobnej). Różne przeglądarki stosują różne podejścia do stosowania zasad tego samego pochodzenia do plików lokalnych.

Domyślam się, że widzisz to w Chrome. Zasady Chrome dotyczące stosowania SOP do plików lokalnych są bardzo ścisłe, nie pozwala nawet na ładowanie plików z tego samego katalogu co dokument. Podobnie Opera. Niektóre inne przeglądarki, takie jak Firefox, umożliwiają ograniczony dostęp do plików lokalnych. Ale w zasadzie używanie ajax z lokalnymi zasobami nie będzie działać w różnych przeglądarkach.

Jeśli testujesz tylko lokalnie coś, co naprawdę wdrożysz w Internecie, zamiast używać plików lokalnych, zainstaluj prosty serwer internetowy i przetestuj za pomocą http://adresów URL. To daje znacznie dokładniejszy obraz bezpieczeństwa.

TJ Crowder
źródło
1
Po przesłaniu nie otrzymuję już Origin zera, ale wciąż dostaję „niedozwolone przez Access-Control-Allow-Origin”.
dudledok,
3
Jeśli ładowany zasób jest zgodny z tym, co pokazano ( $('#result').load('weather.xsl');), nie powinno się to zdarzyć, ponieważ żądanie jest wyraźnie tego samego źródła. Jeśli próbujesz załadować się z innego miejsca (np. $('#result').load('http://somewhere.else/weather.xsl');), To ponownie uruchamiasz SOP, ale w inny sposób. Żądania Ajax są ograniczone do tego samego źródła (patrz link w odpowiedzi) lub jeśli używasz przeglądarki obsługującej CORS, a serwer obsługuje COR, serwer może zdecydować, czy zezwolić na żądanie krzyżowego pochodzenia.
TJ Crowder,
Zmieniłem adres ładowania. Zmiana go z powrotem na pytanie powoduje, że ładuje się dobrze. Dzięki za pomoc
dudledok,
2
Jaki jest najprostszy i najszybszy sposób na skonfigurowanie prostego serwera WWW? Czy usługi IIS byłyby tutaj najprostszym sposobem?
Ciaran Gallagher
13
@CiaranG pobiegłem python -m SimpleHTTPServerz wiersza poleceń, a następnie poszedłem do localhost: 8000, pracowałem dla mnie. Python jest fabrycznie zainstalowany z systemem Mac OS X; może być konieczne zainstalowanie, jeśli używasz innego systemu operacyjnego.
Dave Liepmann
216

Chrome i Safari mają ograniczenia w używaniu ajax z lokalnymi zasobami. Dlatego generuje błąd taki jak

Pochodzenie null jest niedozwolone przez Access-Control-Allow-Origin.

Rozwiązanie: użyj Firefoxa lub prześlij swoje dane na serwer tymczasowy. Jeśli nadal chcesz korzystać z Chrome, zacznij od poniższej opcji;

--allow-file-access-from-files

Więcej informacji, jak dodać powyższy parametr do Chrome: Kliknij prawym przyciskiem myszy ikonę Chrome na pasku zadań, kliknij prawym przyciskiem myszy Google Chrome w wyskakującym oknie i kliknij właściwości i dodaj powyższy parametr w polu tekstowym Cel na karcie Skrót. Będzie to jak poniżej;

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

Mam nadzieję, że to pomoże!

Czołg Gokhan
źródło
19
W Mac OS X możesz uruchomić Chrome z tą opcją, otwierając terminal i wpisując: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files & Uwaga : wersja ostateczna & jest tylko po to, abyś mógł nadal korzystać z terminala i nie jest wymagany. UWAGA: zamknięcie terminalu spowoduje zamknięcie okna Chrome.
Bruno Bernardino,
3
Zrobiłem to wszystko, zamknąłem i otworzyłem. wciąż nie ma (Chrome 27.0.1453.116 m na XP)
mplungjan
Nie mogę dodać tego parametru w systemie Windows 8 ... czy ktoś wie, jak to zrobić? ...
Morty
I 'm uruchomiony z serwera WWW. Co za cholera? Jak mogę dowiedzieć się, gdzie ładuje się lokalne pliki?
Andy,
Kiedy próbuję dodać --allow-file-access-from-files do ścieżki docelowej, pojawia się komunikat „.... niepoprawny”, czy rozwiązanie jest nadal ważne?
alex
48

Chciałem tylko dodać, że odpowiedź „uruchom serwer WWW” wydaje się dość zniechęcająca, ale jeśli masz python w swoim systemie (domyślnie zainstalowany przynajmniej na MacOS i dowolnej dystrybucji Linuksa), jest to tak proste jak:

python -m http.server  # with python3

lub

python -m SimpleHTTPServer  # with python2

Więc jeśli masz plik HTML myfile.htmlw folderze, powiedzmy mydir, wszystko co musisz zrobić to:

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

Następnie skieruj przeglądarkę na:

http://localhost:8000/myfile.html

I gotowe! Działa we wszystkich przeglądarkach , nie wyłączając zabezpieczeń internetowych, zezwalając na lokalne pliki, a nawet ponownie uruchamiając przeglądarkę z opcjami wiersza poleceń.

gozzilli
źródło
2
odpowiednikiem Pythona 3 w systemie Windows jest: python -m http.server [<portNo>]
Aragorn
Python 3: python3 -m http.server
João Nunes
Python 2 w systemie Linux, wybierając port 8080 (lub dowolny inny):python -m SimpleHTTPServer 8080
Rodrigo
2

Chciałbym pokornie dodać, że zgodnie z tym źródłem SO: https://stackoverflow.com/a/14671362/1743693 , tego rodzaju problemy można teraz częściowo rozwiązać, po prostu stosując następującą instrukcję jQuery:

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

Wypróbowałem to na IE10.0.9200 i zadziałało natychmiast (przy użyciu jquery-1.9.0.js).

Na chrome 28.0.1500.95 - ta instrukcja nie działa (dzieje się tak jak w przypadku Davida narzeka w komentarzach pod linkiem powyżej)

Uruchamianie chrome z opcją --allow-file-access-from-files nie działało dla mnie (jak twierdzą Maistora powyżej)

orberkov
źródło
2

Dodając trochę, aby użyć rozwiązania Gokhan do używania:

--allow-file-access-from-files

Teraz wystarczy dołączyć tekst powyżej tekstu docelowego, a następnie spację. pamiętaj, aby zamknąć wszystkie instancje przeglądarki Chrome po dodaniu powyższej właściwości. Teraz uruchom ponownie Chrome przy ikonie, w której dodałeś tę właściwość. To powinno działać dla wszystkich.

saurabh
źródło
Ten parametr został już przedstawiony przez Ghokan Tank, a ustalenie, jak zawsze przeglądarka zaczyna się od tego parametru, nie jest częścią pytania. Ponadto nie można zakładać, że wszyscy korzystają z systemu Microsoft Windows.
jnns
0

Szukałem rozwiązania umożliwiającego wysłanie żądania XHR do serwera z lokalnego pliku HTML i znalazłem rozwiązanie za pomocą Chrome i PHP. (bez Jquery)

JavaScript:

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();

Nagłówek żądania mojego Chrome Origin: null

Mój nagłówek odpowiedzi PHP (zauważ, że „null” to ciąg znaków ). HTTP_REFERER pozwala na cross-origin ze zdalnego serwera na inny.

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

Udało mi się połączyć z moim serwerem. Możesz zignorować nagłówki Poświadczeń, ale działa to dla mnie z ApacheAuthType Basic włączonym

Testowałem zgodność z FF i Operą, Działa w wielu przypadkach, takich jak:

Od adresu IP VM LAN (192.168.0.x) z powrotem do adresu WAN VM (publicznego): port
Od adresu IP VM LAN z powrotem do nazwy domeny zdalnego serwera.
Z lokalnego pliku .HTML na IP VM LAN i / lub VM WAN IP: port,
Z lokalnego pliku .HTML na nazwę domeny zdalnego serwera.
I tak dalej.

Louis Loudog Trottier
źródło
0

Można załadować lokalny plik JavaScript (w drzewie poniżej swojej file:/stronie źródłowej) za pomocą znacznika źródło:

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

Jeśli kodujesz swoje dane wejściowe w JavaScript, tak jak w tym przypadku:

mydata.js :

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

(jest to łatwiejsze dla JSON), wtedy masz swoje „dane” w globalnej zmiennej Javascript do wykorzystania, jak chcesz.

Bogaty
źródło