Jak załadować zawartość pliku tekstowego do zmiennej javascript?

155

Mam plik tekstowy w katalogu głównym mojej aplikacji internetowej http: //localhost/foo.txt i chciałbym załadować go do zmiennej w javascript .. w groovy zrobiłbym to:

def fileContents = 'http://localhost/foo.txt'.toURL().text;
println fileContents;

Jak mogę uzyskać podobny wynik w javascript?

danb
źródło

Odpowiedzi:

142

XMLHttpRequest, czyli AJAX, bez XML.

Dokładny sposób, w jaki to zrobisz, zależy od używanego frameworka JavaScript, ale jeśli pominiemy problemy ze współdziałaniem, Twój kod będzie wyglądał mniej więcej tak:

var client = new XMLHttpRequest ();
client.open ('GET', '/foo.txt');
client.onreadystatechange = function () {
  alert (client.responseText);
}
client.send ();

Zwykle jednak XMLHttpRequest nie jest dostępny na wszystkich platformach, więc pewne oszustwa zostały zrobione. Po raz kolejny najlepszym rozwiązaniem jest użycie frameworka AJAX, takiego jak jQuery.

Dodatkowa uwaga: będzie to działać tylko wtedy, gdy plik foo.txt znajduje się w tej samej domenie. Jeśli znajduje się w innej domenie, zasady zabezpieczeń tego samego pochodzenia uniemożliwiają odczytanie wyniku.

Edward Z. Yang
źródło
1
Obejściem zasady tego samego pochodzenia jest użycie JSONP, który jest również obsługiwany przez jQuery (dla części po stronie klienta)
OneWorld
3
warto dodać, że wewnątrz onreadystatechange można uzyskać dostęp do właściwości readystate obiektu XMLHttpRequest (w przykładzie: client.readystate), aby dowiedzieć się, jaki jest status, ponieważ zdarzenie onreadystatechange jest wywoływane w celu załadowania, załadowania itp. .. więc musisz poczekać na client.readystate == 4 wewnątrz onreadystatechange, zanim będziesz mógł użyć client.responseText.
GameAlchemist
2
@GameAlchemist: natknąłem się na twoją wspaniałą odpowiedź. Chciałem tylko zauważyć, że w większości przeglądarek readyState jest wielkością wielbłąda, więc kod powinien wyglądać if (client.readyState === 4){ }
mniej więcej
6
Dodatkowo możesz zrobić client.onloadendi po prostu uzyskać kompletne dane
Athena
2
Odpowiedź należy zredagować, tak aby obejmowała sprawdzenie client.readyStatewartości właściwości. Głosuję w dół, dopóki nie będzie, ludzie nie będą czytać komentarzy, aby odkryć, że odpowiedź jest tylko częściowo poprawna.
rano
84

oto jak zrobiłem to w jQuery:

jQuery.get('http://localhost/foo.txt', function(data) {
    alert(data);
});
danb
źródło
że nie wydaje się do pracy z zwykły danych tekstowych tabelarycznych ( docs.jquery.com/Specifying_the_Data_Type_for_AJAX_Requests )
Pufferfish
7
Zauważ, że to nie działa, jeśli testujesz go lokalnie, używając file://np file:///example.com/foo.html. : . Firefox skarży się na błąd składni i blokuje Chrome, ponieważ uważa to za żądanie Cross-Origin.
Akronix
@pufferfish będzie działać ze zwykłymi danymi, jeśli określisz dataTypeparametr, patrz api.jquery.com/jQuery.get/
yvesonline
1
@Akronix jeśli pominiesz http://...część, ponieważ znajduje się w tej samej domenie, to zadziała np jQuery.get("foo.txt", ...).
yvesonline
@Akronix Czy istnieje łatwy sposób na przetestowanie go lokalnie? Ciągle otrzymuję błędy żądań z różnych źródeł
ahuff44,
50

Aktualizacja 2019: Korzystanie z funkcji Fetch:

fetch('http://localhost/foo.txt')
  .then(response => response.text())
  .then((data) => {
    console.log(data)
  })

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

Vic
źródło
4
Tak Fetch to (niedawny) standard, a nie zastrzeżone rozszerzenie.
Laurent Caillette
1
Jest rok 2019, a pobieranie to rzecz piękna. To jest sposób na wszystkie nowoczesne przeglądarki, w tym Samsung Internet, które właśnie dogoniły…
Dave Everitt,
Kompaktowy i działający kod, Vic, dziękuję. Czy w celu uzyskania obsługi błędów byłoby możliwe umieszczenie jakiegoś response.ok(lub odpowiednika) gdzieś w kodzie? Nie mam dużego doświadczenia fetch, więc nie znam dokładnego miejsca ustawienia.
Sopalajo de Arrierez
Świetne rozwiązanie. To było super łatwe nawet dla zupełnie początkującego. Przechowywany w zmiennej zamiast console.log w ostatnim kroku, teraz można go używać wszędzie.
AveryFreeman
27

Jeśli potrzebujesz tylko stałego ciągu z pliku tekstowego, możesz dołączyć go jako JavaScript:

// This becomes the content of your foo.txt file
let text = `
My test text goes here!
`;
<script src="foo.txt"></script>
<script>
  console.log(text);
</script>

Ciąg ładowany z pliku staje się dostępny dla JavaScript po załadowaniu. Znak `(backtick) zaczyna i kończy literał szablonu , zezwalając na użycie zarówno znaków", jak i "w bloku tekstowym.

To podejście działa dobrze, gdy próbujesz załadować plik lokalnie, ponieważ Chrome nie zezwala na AJAX w adresach URL ze file://schematem.

Erik Uggeldahl
źródło
1
To byłoby naprawdę sprytne rozwiązanie. Jednak literał szablonu nie jest obsługiwany w IE11, a zmienna „let” znajdowałaby się poza zakresem, gdy znajduje się wewnątrz bloku funkcyjnego, więc ta implementacja jest najeżona niebezpieczeństwem - uwaga.
Neville
7

Należy pamiętać, że Javascript działa na kliencie, a nie na serwerze. Tak naprawdę nie można „załadować pliku” z serwera w Javascript. Dzieje się tak, że Javascript wysyła żądanie do serwera, a serwer odsyła zawartość żądanego pliku. W jaki sposób Javascript otrzymuje zawartość? Do tego służy funkcja wywołania zwrotnego. To znaczy w przypadku Edwarda

    client.onreadystatechange = function() {

w przypadku Danba tak jest

 function(data) {

Ta funkcja jest wywoływana za każdym razem, gdy nadejdą dane. Wersja jQuery niejawnie używa Ajax, po prostu ułatwia kodowanie poprzez hermetyzację tego kodu w bibliotece.

atmelino
źródło
7

Aktualizacja 2020: Używanie Fetch z async / await

const response = await fetch('http://localhost/foo.txt');
const data = await response.text();
console.log(data);

Należy pamiętać, że awaitmożna tego używać tylko w asyncfunkcji. Może to być dłuższy przykład

async function loadFileAndPrintToConsole(url) {
  try {
    const response = await fetch(url);
    const data = await response.text();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

loadFileAndPrintToConsole('https://threejsfundamentals.org/LICENSE');

gman
źródło
5

Powinno to działać w prawie wszystkich przeglądarkach:

var xhr=new XMLHttpRequest();
xhr.open("GET","https://12Me21.github.io/test.txt");
xhr.onload=function(){
    console.log(xhr.responseText);
}
xhr.send();

Dodatkowo jest nowe FetchAPI:

fetch("https://12Me21.github.io/test.txt")
.then( response => response.text() )
.then( text => console.log(text) )
12Me21
źródło
1

Pracując z jQuery zamiast używać jQuery.getnp

jQuery.get("foo.txt", undefined, function(data) {
    alert(data);
}, "html").done(function() {
    alert("second success");
}).fail(function(jqXHR, textStatus) {
    alert(textStatus);
}).always(function() {
    alert("finished");
});

możesz użyć, .loadco daje znacznie bardziej skondensowaną formę:

$("#myelement").load("foo.txt");

.loaddaje również opcję załadowania częściowych stron, co może się przydać, patrz api.jquery.com/load/ .

yvesonline
źródło
-3

Jeśli twoje dane wejściowe miały strukturę XML, możesz użyć importXMLfunkcji. (Więcej informacji tutaj w quirksmode ).

Jeśli to nie jest XML i nie ma równoważnej funkcji do importowania zwykłego tekstu, możesz otworzyć go w ukrytej ramce iframe, a następnie przeczytać zawartość stamtąd.

nickf
źródło