XMLHttpRequest Origin null jest niedozwolony Kontrola dostępu-Allow-Origin dla pliku: /// do pliku: /// (bez serwera)

209

Próbuję utworzyć witrynę internetową, którą można pobrać i uruchomić lokalnie, uruchamiając plik indeksu.

Wszystkie pliki są lokalne, żadne zasoby nie są używane online.

Kiedy próbuję użyć wtyczki AJAXSLT dla jQuery do przetworzenia pliku XML z szablonem XSL (w podkatalogach), otrzymuję następujące błędy:

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/data/home.xml. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/assets/xsl/main.xsl. Origin null is not allowed by Access-Control-Allow-Origin.

Plik indeksu wysyłający zapytanie jest file:///C:/path/to/XSL%20Website/index.htmlprzechowywany w, gdy używane są pliki JavaScript file:///C:/path/to/XSL%20Website/assets/js/.

Jak mogę rozwiązać ten problem?

Kevin Herrera
źródło

Odpowiedzi:

177

W przypadkach, w których uruchomienie lokalnego serwera WWW nie jest możliwe, możesz zezwolić Chromeowi na dostęp do file://plików za pomocą przełącznika przeglądarki. Po kilku kopaniach znalazłem tę dyskusję , która wspomina przełącznik przeglądarki w otwierającym poście. Uruchom instancję Chrome za pomocą:

chrome.exe --allow-file-access-from-files

Może to być akceptowalne w środowiskach programistycznych, ale niewiele więcej. Na pewno nie chcesz tego cały czas. To wciąż wydaje się być kwestią otwartą (od stycznia 2011 r.).

Zobacz także: Problemy z jQuery getJSON przy użyciu lokalnych plików w Chrome

Courtney Christensen
źródło
1
@Rich, cieszę się, że pomogło! Zastanawiam się, czy popyt na Google będzie większy w przypadku aplikacji opartych na przeglądarce. Myślę, że popyt wzrośnie.
Courtney Christensen
4
było to pomocne dla macs OS X cweagans.net/blog/2011/1/24/...
Kinet
1
Dzięki, zastanawiałem się, gdzie źle zakodowałem, wygląda na to, że problem dotyczy przeglądarki.
Arda
4
Czy jest jakiś powód --allow-file-access-from-files nie rozwiązuje problemu. Po prostu próbuję załadować plik skryptu, taki jak $ .getScript („application.js”); i uzyskaj błąd opisany w pytaniu.
Denzo,
1
Działa to jednak „Przed wykonaniem polecenia upewnij się, że wszystkie okno Chrome jest zamknięte i nie działa w inny sposób. Lub parametr wiersza poleceń nie będzie skuteczny.” Chrome.exe --allow-file-access-from- pliki „” ( stackoverflow.com/a/4208455/1272428 )
rluks,
87

Zasadniczo jedynym sposobem na poradzenie sobie z tym jest uruchomienie serwera WWW na localhost i obsługa go stamtąd.

Przeglądarka nie jest pewna, aby zezwolić żądaniu ajax na dostęp do dowolnego pliku na twoim komputerze, dlatego większość przeglądarek traktuje żądania „file: //” jako niepochodzące do celów „ Polityki tego samego pochodzenia

Uruchomienie serwera WWW może być tak proste, jak cdwejście do katalogu, w którym znajdują się i działają pliki:

python -m SimpleHTTPServer
Singletoned
źródło
1
Mam nadzieję opracować rozwiązanie, które nie będzie wymagało od użytkownika używania niczego poza przeglądarką internetową. Korzystanie z Pythona, jakiegokolwiek interpretera lub jakiegokolwiek niesystemowego oprogramowania agnostycznego nie jest wykonalne.
Kevin Herrera
5
Cóż, jedynym innym rozwiązaniem, jakie mogę wymyślić, jest załadowanie całego pliku na jedną stronę, abyś nie musiał składać żadnych żądań ajax do systemu plików.
Singletoned
2
Dziękuję @ Singletoned! Korzystam z twojego rozwiązania i jest to bardzo przydatne!
Hendy Irawan
4
A jeśli używasz Python 3, polecenie byłoby python -m http.server.
alextercete
4

Oto skrypt Apple, który uruchomi Chrome z włączonym przełącznikiem --allow-file-access-from-files, dla deweloperów OSX / Chrome:

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"    
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
ericsoco
źródło
14
Można po prostu użyć otwarty (1) , aby dodać flagi: open -a 'Google Chrome' --args --allow-file-access-from-files.
Josh Lee
4

To rozwiązanie pozwoli Ci załadować lokalny skrypt za pomocą jQuery.getScript (). Jest to ustawienie globalne, ale można również ustawić opcję crossDomain na podstawie żądania.

$.ajaxPrefilter( "json script", function( options ) {
  options.crossDomain = true;
});
Renaud
źródło
działało jak urok przy ładowaniu lokalnego pliku js z lokalnego pliku HTML! dzięki, dokładnie to, czego potrzebowałem.
user1577390,
4

Co z użyciem funkcji FileReader javascript do otwarcia pliku lokalnego, tj .:

<input type="file" name="filename" id="filename">
<script>
$("#filename").change(function (e) {
  if (e.target.files != undefined) {
    var reader = new FileReader();
    reader.onload = function (e) {
        // Get all the contents in the file
        var data = e.target.result; 
        // other stuffss................            
    };
    reader.readAsText(e.target.files.item(0));
  }
});
</script>

Teraz kliknij Choose fileprzycisk i przejdź do plikufile:///C:/path/to/XSL%20Website/data/home.xml

suhailvs
źródło
3

Uruchomienie chrom jak tak do obejścia tego ograniczenia: open -a "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --args --allow-file-access-from-files.

Pochodzi z komentarza Josha Lee, ale musiałem podać pełną ścieżkę do Google Chrome, aby uniknąć otwierania Google Chrome z mojej partycji Windows (w Parallels).

Szlagier
źródło
2

Sposób, w jaki właśnie to obejrzałem, nie polega wcale na korzystaniu z XMLHTTPRequest, ale na dołączeniu potrzebnych danych do osobnego pliku javascript. (W moim przypadku potrzebowałem binarnego obiektu blob SQLite do użycia z https://github.com/kripken/sql.js/ )

Utworzyłem plik o nazwie base64_data.js(i użyłem go btoa()do konwersji potrzebnych danych i wstawienia go, <div>aby móc go skopiować).

var base64_data = "U1FMaXRlIGZvcm1hdCAzAAQA ...<snip lots of data> AhEHwA==";

a następnie zawarł dane w html jak normalny javascript:

<div id="test"></div>

<script src="base64_data.js"></script>
<script>
    data = atob(base64_data);
    var sqldb = new SQL.Database(data);
    // Database test code from the sql.js project
    var test = sqldb.exec("SELECT * FROM Genre");
    document.getElementById("test").textContent = JSON.stringify(test);
</script>

Wyobrażam sobie, że modyfikacja tego do odczytu JSON, a może nawet XML, byłaby trywialna; Zostawię to jako ćwiczenie dla czytelnika;)

Anthony Briggs
źródło
1

Można spróbować umieścić 'Access-Control-Allow-Origin':'*'w response.writeHead(, {[here]}).

Shikon
źródło
6
skąd pochodzi odpowiedź.writeHead, jak to nazwać i gdzie? Czy możesz podać więcej przykładów? Pamiętaj, że jest to lokalny system plików, a nie serwer. Rozumiem, że wartość można ustawić tylko z serwera?
Joseph Astrahan
0

użyj „serwera WWW dla aplikacji Chrome”. (faktycznie masz go na swoim komputerze, niezależnie od tego, czy wiesz. Po prostu wyszukaj go w Cortanie!). otwórz go i kliknij „wybierz plik”, wybierz folder z plikiem. nie wybieraj pliku. wybierz folder plików, a następnie kliknij łącze (łącza) pod przyciskiem „wybierz folder”.

jeśli nie zabierze Cię do pliku, dodaj nazwę pliku do urs. lubię to:

   https://127.0.0.1:8887/fileName.txt

link do serwera WWW dla chrome: kliknij mnie

osoba ludzka
źródło