Jak otworzyć plik na dysku lokalnym za pomocą JavaScript?

155

Próbowałem otworzyć plik za pomocą

window.open("file:///D:/Hello.txt");

Przeglądarka nie pozwala w ten sposób otwierać pliku lokalnego, prawdopodobnie ze względów bezpieczeństwa. Chcę użyć danych pliku po stronie klienta. Jak mogę czytać lokalny plik w JavaScript?

Joval
źródło

Odpowiedzi:

238

Oto przykład wykorzystujący FileReader:

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    displayContents(contents);
  };
  reader.readAsText(file);
}

function displayContents(contents) {
  var element = document.getElementById('file-content');
  element.textContent = contents;
}

document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);
<input type="file" id="file-input" />
<h3>Contents of the file:</h3>
<pre id="file-content"></pre>


Okular

http://dev.w3.org/2006/webapi/FileAPI/

Zgodność z przeglądarkami

  • IE 10+
  • Firefox 3.6+
  • Chrome 13+
  • Safari 6.1+

http://caniuse.com/#feat=fileapi

Paolo Moretti
źródło
1
Zaledwie sekunda, gdy przeładowuję ten sam ostatni plik, zawartość się nie zmienia (mówię o jego zawartości, kiedy edytuję tekst pliku). Możesz pomóc?
Hydroper
1
@SamusHands Tak, masz rację, mogę odtworzyć problem w Safari i Chrome (działa dobrze w Firefoksie). Ustawienie wartości wejścia nullna każde onClickzdarzenie powinno załatwić sprawę, patrz: stackoverflow.com/a/12102992/63011
Paolo Moretti
3
To dobry przykład FileReader, ale komentarz do displayContentspowyższego: zwróć uwagę, że innerHTMLtakie ustawienie z niezaufaną zawartością może stanowić lukę w zabezpieczeniach. (Aby zobaczyć to na własne oczy, utwórz plik bad.txtzawierający coś w rodzaju <img src="/nonexistent" onerror="alert(1);">i zobacz, że alert zostanie wykonany - może to być bardziej złośliwy kod).
ShreevatsaR
2
@ShreevatsaR naprawdę dobra uwaga. Mój fragment to tylko przykład, ale masz rację, nie powinien promować złych nawyków związanych z bezpieczeństwem. Wymieniłem innerHTMLz textContent. Dzięki za komentarz.
Paolo Moretti
1
@TeylerHalama Możesz również użyć do tego DOMContentLoadedwydarzenia.
Paolo Moretti
59

Funkcja fileReader HTML5 pozwala na przetwarzanie lokalnych plików, ale MUSZĄ one zostać wybrane przez użytkownika, nie możesz zrootować dysku użytkownika w poszukiwaniu plików.

Obecnie używam tego z wersjami programistycznymi Chrome (6.x). Nie wiem, jakie inne przeglądarki to obsługują.

HBP
źródło
3
Tak, teraz jest to możliwe dzięki HTML5. Spójrz tutaj
Flavien Volken
1
Szybkie skanowanie przywoływanej specyfikacji (ostatnia aktualizacja 2012-07-12) pokazuje brak możliwości zapisu plików, a jedynie odczyt.
HBP
26

Ponieważ nie mam życia i chcę mieć te 4 punkty reputacji, abym mógł pokazać swoją miłość ludziom, którzy są naprawdę dobrzy w kodowaniu (popieraj ich), podzieliłem się moją adaptacją kodu Paolo Morettiego . Po prostu użyj openFile(funkcji do wykonania z zawartością pliku jako pierwszym parametrem) .

function dispFile(contents) {
  document.getElementById('contents').innerHTML=contents
}
function clickElem(elem) {
	// Thx user1601638 on Stack Overflow (6/6/2018 - /programming/13405129/javascript-create-and-save-file )
	var eventMouse = document.createEvent("MouseEvents")
	eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
	elem.dispatchEvent(eventMouse)
}
function openFile(func) {
	readFile = function(e) {
		var file = e.target.files[0];
		if (!file) {
			return;
		}
		var reader = new FileReader();
		reader.onload = function(e) {
			var contents = e.target.result;
			fileInput.func(contents)
			document.body.removeChild(fileInput)
		}
		reader.readAsText(file)
	}
	fileInput = document.createElement("input")
	fileInput.type='file'
	fileInput.style.display='none'
	fileInput.onchange=readFile
	fileInput.func=func
	document.body.appendChild(fileInput)
	clickElem(fileInput)
}
Click the button then choose a file to see its contents displayed below.
<button onclick="openFile(dispFile)">Open a file</button>
<pre id="contents"></pre>

SignatureSmileyfaceProductions
źródło
2
Dzięki, był pomocny. Pamiętaj jednak, że zamiast tego kodu, który masz clickElem(), możesz po prostu zadzwonić fileInput.click(). (przynajmniej w najnowszej wersji Chrome)
Venryx
6

Próbować

function readFile(file) {
  return new Promise((resolve, reject) => {
    let fr = new FileReader();
    fr.onload = x=> resolve(fr.result);
    fr.readAsText(file);
})}

ale użytkownik musi podjąć działania, aby wybrać plik

Kamil Kiełczewski
źródło
Właśnie zobaczyłem msg.innerText i po raz pierwszy dowiedziałem się, że do niektórych elementów identyfikowanych za pomocą identyfikatorów można uzyskać dostęp za pomocą identyfikatorów jako nazw zmiennych lub właściwości obiektu okna.
fmalina
więc odpowiedź brzmi: nie możemy . html wydaje się idealny do interakcji z dokumentami! ale nie wszystko da się podać. Dostęp do plików lokalnych byłby miły
jota
@yota - przeglądarka wymusza interakcję (i należy być świadomym) prawdopodobnie ze względów bezpieczeństwa
Kamil Kiełczewski
-4

Metoda żądania xmlhttp nie jest prawidłowa dla plików na dysku lokalnym, ponieważ zabezpieczenia przeglądarki nam na to nie pozwalają.Ale możemy nadpisać zabezpieczenia przeglądarki, tworząc skrót -> kliknięcie prawym przyciskiem myszy -> właściwości W przeglądarce docelowej "... location path.exe "append --allow-file-access-from-files. Jest to testowane na chrome, jednak należy uważać, aby wszystkie okna przeglądarki były zamknięte, a kod uruchamiany z przeglądarki otwartej za pomocą tego skrótu.

user2450701
źródło
-7

Nie możesz. Nowe przeglądarki, takie jak Firefox, Safari itp., Blokują protokół „pliku”. Będzie działać tylko na starych przeglądarkach.

Musisz przesłać żądane pliki.

Youssef
źródło
-9

JavaScript zazwyczaj nie może uzyskać dostępu do plików lokalnych w nowych przeglądarkach, ale obiekt XMLHttpRequest może służyć do odczytywania plików. Więc to właśnie Ajax (a nie Javascript) czyta plik.

Jeśli chcesz odczytać plik abc.txt, możesz napisać kod jako:

var txt = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
  if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
    txt = xmlhttp.responseText;
  }
};
xmlhttp.open("GET","abc.txt",true);
xmlhttp.send();

Teraz txtzawiera zawartość pliku abc.txt.

Karanpreet Singh
źródło
61
Ajax to JavaScript.
The Muffin Man
4
@TheMuffinMan i XML. (Asynchronus Javascript i XML)
Quintec
9
Ta odpowiedź nie ma znaczenia, ponieważ operator zapytał, jak otwierać pliki znajdujące się po stronie klienta, a nie pliki znajdujące się na serwerze.
Thomas Nguyen
4
@ThomasNguyen, to pytanie jest pierwszym wynikiem wyszukiwania w Google „otwartego pliku javascript”, a mimo to ta odpowiedź jest korzystna.
Nathan Goings
@ThomasNguyen Zgadzam się, ale możliwym obejściem bez FileReader może być przesłanie pliku na serwer i odczytanie go stamtąd. Mimo to odrzuciłem tę odpowiedź.
inf3rno