Clientseitiges Lesen von Dateiinhalten in Javascript in diversen Browsern
Lesezeit: 6 Minuten
Damovisa
Ich versuche, eine reine Skriptlösung zum Lesen des Inhalts einer Datei auf einem Clientcomputer über einen Browser bereitzustellen.
Ich habe eine Lösung, die mit Firefox und Internet Explorer funktioniert. Es ist nicht schön, aber ich probiere im Moment nur Dinge aus:
function getFileContents() {
var fileForUpload = document.forms[0].fileForUpload;
var fileName = fileForUpload.value;
if (fileForUpload.files) {
var fileContents = fileForUpload.files.item(0).getAsBinary();
document.forms[0].fileContents.innerHTML = fileContents;
} else {
// try the IE method
var fileContents = ieReadFile(fileName);
document.forms[0].fileContents.innerHTML = fileContents;
}
}
function ieReadFile(filename)
{
try
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.OpenTextFile(filename, 1);
var contents = fh.ReadAll();
fh.Close();
return contents;
}
catch (Exception)
{
return "Cannot open file :(";
}
}
Ich kann anrufen getFileContents() und es wird den Inhalt in die schreiben fileContents Textbereich.
Gibt es eine Möglichkeit, dies in anderen Browsern zu tun?
Im Moment mache ich mir am meisten Sorgen um Safari und Chrome, aber ich bin offen für Vorschläge für andere Browser.
Bearbeiten: Auf die Frage “Warum wollen Sie das tun?”:
Grundsätzlich möchte ich den Dateiinhalt zusammen mit einem Einmalpasswort auf der Clientseite hashen, damit ich diese Informationen als Bestätigung zurücksenden kann.
Nicht, dass ich eine Antwort hätte, aber nur aus Gründen der Klarheit, müssen Sie den Speicherort der Datei kennen? Wenn nicht, muss der Speicherort der Datei aus einer Dateieingabe gelesen werden oder kann es eine Textbox/Textarea/was auch immer sein?
– Darko Z
15. April 2009 um 2:14 Uhr
Gute Frage. Nein, es ist mir egal, woher die Datei kommt, nur ihr Inhalt. Die Verwendung einer Dateieingabe erscheint mir jedoch sinnvoll, da es sich um natives HTML handelt – es gibt eine Sache weniger, die ich tun muss.
– Damovisa
15. April 2009 um 2:45 Uhr
warum willst du das überhaupt machen? der server soll das machen.
– geowa4
15. April 2009 um 23:48 Uhr
Ok, kurz gesagt: Ein Benutzer gibt ein Passwort ein und wählt eine Datei aus. Das Passwort wird mit dem Dateiinhalt gehasht und zusammen mit der Datei an den Server gesendet. Wenn es dort ankommt, kann ich überprüfen, ob das richtige Client-Passwort verwendet wurde.
– Damovisa
16. April 2009 um 0:48 Uhr
2021: let a = await file.text();
– Harschal Parekh
21. Oktober 2021 um 11:18 Uhr
Brian Campell
Bearbeitet, um Informationen über die Datei-API hinzuzufügen
Da ich diese Antwort ursprünglich geschrieben habe, ist die Datei-API wurde als Standard vorgeschlagen und in den meisten Browsern implementiert (ab IE 10, der Unterstützung für FileReader API hier beschrieben, allerdings noch nicht die File API). Die API ist etwas komplizierter als die ältere Mozilla-API, da sie darauf ausgelegt ist, das asynchrone Lesen von Dateien, eine bessere Unterstützung für Binärdateien und die Dekodierung verschiedener Textkodierungen zu unterstützen. Es gibt einige Dokumentationen, die im Mozilla Developer Network verfügbar sind sowie verschiedene Beispiele online. Sie würden es wie folgt verwenden:
var file = document.getElementById("fileForUpload").files[0];
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
document.getElementById("fileContents").innerHTML = evt.target.result;
}
reader.onerror = function (evt) {
document.getElementById("fileContents").innerHTML = "error reading file";
}
}
Ursprüngliche Antwort
In WebKit (also Safari und Chrome) scheint es keine Möglichkeit zu geben, dies zu tun. Die einzigen Schlüssel, die a Datei Objekt hat sind fileName und fileSize. Entsprechend der Nachricht begehen für die Unterstützung von Dateien und Dateilisten sind diese inspiriert von Mozillas File-Objektaber sie scheinen nur eine Teilmenge der Funktionen zu unterstützen.
Wenn Sie dies ändern möchten, können Sie dies jederzeit tun Patch senden zum WebKit-Projekt. Eine andere Möglichkeit wäre, die Mozilla-API zur Aufnahme vorzuschlagen HTML5; der WASWG Mailingliste ist wahrscheinlich der beste Ort dafür. Wenn Sie das tun, ist es viel wahrscheinlicher, dass es zumindest in ein paar Jahren eine browserübergreifende Möglichkeit gibt, dies zu tun. Natürlich bedeutet das Einreichen eines Patches oder eines Vorschlags zur Aufnahme in HTML 5 einige Arbeit, um die Idee zu verteidigen, aber die Tatsache, dass Firefox es bereits implementiert, gibt Ihnen einen Anfang.
Danke dafür – ich glaube nicht, dass ich zu diesem Zeitpunkt engagiert genug bin, um einen Patch einzureichen. Es ist etwas, das Sie wahrscheinlich ohne Ihr Wissen sowieso nicht wollen würden. Es bricht irgendwie die Browser-Sandbox …
– Damovisa
16. April 2009 um 2:23 Uhr
Die Browser-Sandbox wird nicht beschädigt, da Sie sich bewusst dafür entschieden haben, diese Datei hochzuladen. Wenn es zum Server gelangen kann, kann es zum Browser zurückkehren, nur mit einem zusätzlichen Roundtrip. Angesichts der Arbeit, die darauf verwendet wird, den Offline-Modus für Web-Apps zum Laufen zu bringen, wäre dies eine vernünftige Funktion.
– Brian Campell
16. April 2009 um 2:31 Uhr
Mm, eigentlich ist das ein fairer Punkt. Es gab eine Benutzerinteraktion, um diese Datei auszuwählen. Danke.
– Damovisa
17. April 2009 um 0:42 Uhr
@Damovisa Ich weiß nicht, ob Sie sich noch darum kümmern, aber ich dachte, ich würde meine Antwort aktualisieren, um die neue Datei-API zu erwähnen, die das tut, wonach Sie suchen, und in Firefox, Chrome und nächtlichen Builds von implementiert ist Safari.
– Brian Campell
19. April 2011 um 15:47 Uhr
sollten die Ereignishandler nicht vor dem Aufruf angehängt werden readAsText ?
– GoofballLogik
19. Januar 2018 um 14:19 Uhr
Um eine vom Benutzer ausgewählte Datei mit einem Datei-Öffnen-Dialog zu lesen, können Sie die verwenden <input type="file"> Schild. Sie können finden Informationen dazu von MSDN. Wenn die Datei ausgewählt ist, können Sie die verwenden FileReader-API um den Inhalt zu lesen.
function onFileLoad(elementId, event) {
document.getElementById(elementId).innerText = event.target.result;
}
function onChooseFile(event, onLoadFileHandler) {
if (typeof window.FileReader !== 'function')
throw ("The file API isn't supported on this browser.");
let input = event.target;
if (!input)
throw ("The browser does not properly implement the event object");
if (!input.files)
throw ("This browser does not support the `files` property of the file input.");
if (!input.files[0])
return undefined;
let file = input.files[0];
let fr = new FileReader();
fr.onload = onLoadFileHandler;
fr.readAsText(file);
}
Derzeit (September 2020) wird dies in Chrome und Firefox unterstützt, für andere Browser müssen Sie ein Polyfill laden, z Blob-Polyfill.
Das funktioniert gut
function onClick(event) {
filecontent = "";
var myFile = event.files[0];
var reader = new FileReader();
reader.addEventListener('load', function (e) {
filecontent = e.target.result;
});
reader.readAsBinaryString(myFile);
}
Nicht, dass ich eine Antwort hätte, aber nur aus Gründen der Klarheit, müssen Sie den Speicherort der Datei kennen? Wenn nicht, muss der Speicherort der Datei aus einer Dateieingabe gelesen werden oder kann es eine Textbox/Textarea/was auch immer sein?
– Darko Z
15. April 2009 um 2:14 Uhr
Gute Frage. Nein, es ist mir egal, woher die Datei kommt, nur ihr Inhalt. Die Verwendung einer Dateieingabe erscheint mir jedoch sinnvoll, da es sich um natives HTML handelt – es gibt eine Sache weniger, die ich tun muss.
– Damovisa
15. April 2009 um 2:45 Uhr
warum willst du das überhaupt machen? der server soll das machen.
– geowa4
15. April 2009 um 23:48 Uhr
Ok, kurz gesagt: Ein Benutzer gibt ein Passwort ein und wählt eine Datei aus. Das Passwort wird mit dem Dateiinhalt gehasht und zusammen mit der Datei an den Server gesendet. Wenn es dort ankommt, kann ich überprüfen, ob das richtige Client-Passwort verwendet wurde.
– Damovisa
16. April 2009 um 0:48 Uhr
2021:
let a = await file.text();
– Harschal Parekh
21. Oktober 2021 um 11:18 Uhr