Lokaler Dateizugriff mit JavaScript

177

Gibt es eine lokale Dateimanipulation, die mit JavaScript durchgeführt wurde? Ich bin auf der Suche nach einer Lösung, die ohne Installationsaufwand wie Adobe AIR ausgeführt werden kann .

Insbesondere möchte ich den Inhalt aus einer Datei lesen und diesen Inhalt in eine andere Datei schreiben. An diesem Punkt mache ich mir keine Sorgen um das Erhalten von Berechtigungen und gehe nur davon aus, dass ich bereits über die vollständigen Berechtigungen für diese Dateien verfüge.

Jared
quelle
1
Chrom XHR spezifisch: stackoverflow.com/questions/4819060/…
Ciro Santilli 3 冠状 病 六四 事件 3

Antworten:

87

Wenn der Benutzer eine Datei über auswählt <input type="file">, können Sie diese Datei mithilfe der Datei-API lesen und verarbeiten .

Das Lesen oder Schreiben beliebiger Dateien ist nicht zulässig. Es ist eine Verletzung des Sandkastens. Aus Wikipedia -> Javascript -> Sicherheit :

JavaScript und das DOM bieten böswilligen Autoren die Möglichkeit, Skripte bereitzustellen, die auf einem Client-Computer über das Web ausgeführt werden. Browser-Autoren begrenzen dieses Risiko mit zwei Einschränkungen. Erstens werden Skripte in einer Sandbox ausgeführt, in der sie nur webbezogene Aktionen ausführen können, keine allgemeinen Programmieraufgaben wie das Erstellen von Dateien .

2016 UPDATE : Der direkte Zugriff auf das Dateisystem ist über die Dateisystem-API möglich , die nur von Chrome und Opera unterstützt wird und möglicherweise nicht von anderen Browsern implementiert wird (mit Ausnahme von Edge ). Für Details siehe Kevins Antwort .

Chase Seibert
quelle
28
Verdammt. Das ist natürlich dumm. Javascript ist angeblich eine anwendungsunabhängige Skriptsprache. Nicht jede Anwendung ist ein Webbrowser. Ich bin hierher gekommen, weil ich mich zum Beispiel für das Erstellen von Skripten für Photoshop interessiere. Selbst wenn einige Anwendungen keine Dateizugriffsklassen bereitstellen, ist es sinnvoll, sie für die Anwendungen zu standardisieren, bei denen sie angemessen sind - eine standardmäßige, aber optionale Funktion, sodass die Erfahrung einer App übertragbar ist, auch wenn sie nicht universell anwendbar ist. Was ich in Photoshop lerne, kann nicht einmal auf andere Javascript-Hosts übertragen werden, die den Dateizugriff ermöglichen.
Steve314
27
Javascript die Sprache und tun, was die Hosting-Umgebung erlaubt. SpiderMonkey kann alles, was jede andere Sprache kann. Javascript im Browser ist eine Sandbox.
35
Diese Antwort mag vor 3 Jahren richtig gewesen sein, aber sie ist sicherlich nicht mehr richtig. Siehe die Antwort von @Horst Walter auf HTML5. Oder gehen Sie hier: html5rocks.com/de/tutorials/file/dndfiles
james.garriss
@ james.garriss Ja, eigentlich war es vor drei Jahren auch nicht ganz richtig. Diese Seite hat mich gelehrt , wie man lesen / schreiben mit Firefox im Jahr 2003 web.archive.org/web/20031229011919/http://www.captain.at/... (bulit für XUL aber in dem Browser mit XPCOM) und Microsoft hatte Javscript-Shell-Scripting im Stil von node.js in den 1990er Jahren (und FileIO im Browser mit ActiveX verfügbar)
original_username
Nicht mehr möglich
SysDragon
158

Nur ein Update der HTML5-Funktionen finden Sie unter http://www.html5rocks.com/en/tutorials/file/dndfiles/ . In diesem hervorragenden Artikel wird der lokale Dateizugriff in JavaScript ausführlich erläutert. Zusammenfassung aus dem genannten Artikel:

Die Spezifikation bietet mehrere Schnittstellen für den Zugriff auf Dateien aus einem "lokalen" Dateisystem :

  1. Datei - eine einzelne Datei; Bietet schreibgeschützte Informationen wie Name, Dateigröße, MIME-Typ und einen Verweis auf das Dateihandle.
  2. FileList - eine Array-ähnliche Folge von Dateiobjekten. (Denken Sie an <input type="file" multiple>ein Verzeichnis von Dateien oder ziehen Sie es vom Desktop.)
  3. Blob - Ermöglicht das Aufteilen einer Datei in Bytebereiche.

Siehe den Kommentar von Paul D. Waite unten.

Horst Walter
quelle
7
Es ist nicht gerade ein echtes Dateisystem, wie wir es mit dem Java- oder Flash-Plugin haben. Beispielsweise können wir die Dateien nicht auf dem Desktop des Benutzers auflisten, es sei denn, er wählt sie zuerst selbst aus.
Pacerier
9
Es sieht so aus, als würden diese APIs aufgegeben: siehe w3.org/TR/file-writer-api und html5rocks.com/en/tutorials/file/filesystem
Paul D. Waite
4
Vorsicht dort, angesichts der Form des W3C, nützliche Technologie wegzuschnappen. Die Dateisystem-API, die nur in Chrome implementiert ist, wird nicht weiterentwickelt. Die Datei- API hat universelle Unterstützung, wird als W3C-Arbeitsentwurf akzeptiert und wir können uns ein Leben ohne sie nicht mehr vorstellen. Natürlich sind wir immer noch in einem Browser und müssen warten, bis der Benutzer uns die Datei bringt, aber dies erweitert die Reichweite von Web-Apps dramatisch und wird nicht so schnell verschwinden.
Bbsimonbb
21

UPDATE Diese Funktion wurde seit Firefox 17 entfernt (siehe https://bugzilla.mozilla.org/show_bug.cgi?id=546848 ).


In Firefox können Sie (der Programmierer) dies aus einer JavaScript-Datei heraus tun:

netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");

und Sie (der Browser-Benutzer) werden aufgefordert, den Zugriff zuzulassen. (Für Firefox müssen Sie dies nur einmal bei jedem Start des Browsers tun.)

Wenn der Browserbenutzer eine andere Person ist, muss er die Berechtigung erteilen.

Jason S.
quelle
6
Dies gibt einen Fehler, dass es veraltet ist und Sie können dies nur in einer Erweiterung tun, nicht Website Javascript
Esailija
4
Wie dieser Link zeigt, wurde diese Funktion in späteren Firefox-Versionen entfernt. support.mozilla.org/en-US/questions/944433
Makan Tayebi
3
Oh, das ist scheiße. Ich bekomme Sicherheit und all das, aber wir brauchen eine Möglichkeit, Vertrauen zu gewähren, um unsere eigenen Javascript-Dateien lokal auszuführen.
Jason S
sicher. und ich habe noch keinen anderen Weg gefunden, dies zu tun.
Makan Tayebi
2
Bitte aktualisieren Sie die Antwort, um zu zeigen, dass sie veraltet ist. Vielen Dank.
Jpaugh
20

Wie bereits erwähnt, können die FileSystem- und File- APIs zusammen mit der FileWriter- API zum Lesen und Schreiben von Dateien aus dem Kontext einer Browserregisterkarte / eines Browserfensters auf einen Clientcomputer verwendet werden.

Im Zusammenhang mit den APIs FileSystem und FileWriter sollten Sie einige Dinge beachten, von denen einige erwähnt wurden, die jedoch wiederholt werden sollten:

  • Implementierungen der APIs sind derzeit nur in Chromium-basierten Browsern (Chrome & Opera) vorhanden.
  • Beide APIs wurden am 24. April 2014 aus dem W3C-Standard-Track entfernt und sind ab sofort proprietär
  • Das Entfernen der (jetzt proprietären) APIs aus zukünftigen Implementierungen von Browsern ist möglich
  • Ein Sandkasten (ein Speicherort auf der Festplatte, außerhalb dessen Dateien keine Auswirkungen haben können) wird zum Speichern der mit den APIs erstellten Dateien verwendet
  • Ein virtuelles Dateisystem (eine Verzeichnisstruktur, die nicht unbedingt in derselben Form auf der Festplatte vorhanden ist wie beim Zugriff über den Browser) repräsentiert die mit den APIs erstellten Dateien

Hier sind einfache Beispiele dafür, wie die APIs direkt und indirekt zusammen verwendet werden, um diese Dinge zu tun:

BakedGoods *

Datei schreiben:

bakedGoods.set({
    data: [{key: "testFile", value: "Hello world!", dataFormat: "text/plain"}],
    storageTypes: ["fileSystem"],
    options: {fileSystem:{storageType: Window.PERSISTENT}},
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

Datei lesen:

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

Verwenden der Rohdatei-, FileWriter- und FileSystem-APIs

Datei schreiben:

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Datei lesen:

function onQuotaRequestSuccess(grantedQuota)
{

    function getfile(directoryEntry)
    {

        function readFile(fileEntry)
        {

            function read(file)
            {
                var fileReader = new FileReader();

                fileReader.onload = function(){var fileData = fileReader.result};
                fileReader.readAsText(file);             
            }

            fileEntry.file(read);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: false},
            readFile
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, getFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Obwohl die FileSystem- und FileWriter-APIs nicht mehr auf der Standardspur sind, kann ihre Verwendung meiner Meinung nach in einigen Fällen gerechtfertigt sein, weil:

  • Erneutes Interesse der nicht implementierenden Browser-Anbieter kann sie direkt wieder darauf setzen
  • Die Marktdurchdringung der Implementierung von (Chromium-basierten) Browsern ist hoch
  • Google (der Hauptverursacher von Chromium) hat den APIs kein Datum für das Ende der Lebensdauer angegeben

Ob "einige Fälle" Ihre eigenen umfassen, müssen Sie jedoch selbst entscheiden.

* BakedGoods wird von niemand anderem als diesem Kerl hier gepflegt :)

Kevin
quelle
7

Mit NW.js können Sie Desktop-Anwendungen mit Javascript erstellen, ohne alle Sicherheitsbeschränkungen zu beachten, die normalerweise für den Browser gelten. Sie können also ausführbare Dateien mit einer Funktion ausführen oder Dateien erstellen / bearbeiten / lesen / schreiben / löschen. Sie können auf die Hardware zugreifen, z. B. auf die aktuelle CPU-Auslastung oder den insgesamt verwendeten RAM usw.

Sie können damit eine Windows-, Linux- oder Mac-Desktop-Anwendung erstellen, für die keine Installation erforderlich ist.

Hier ist ein Framework für NW.js, die universelle GUI:

Jaredcheeda
quelle
1
Es ist auch möglich, mit Electron auf lokale Dateien zuzugreifen , einem ähnlichen Framework für JavaScript-Desktopanwendungen.
Anderson Green
6

Wenn Sie unter Windows bereitstellen, bietet der Windows Script Host eine sehr nützliche JScript-API für das Dateisystem und andere lokale Ressourcen. Das Einbinden von WSH-Skripten in eine lokale Webanwendung ist jedoch möglicherweise nicht so elegant, wie Sie es wünschen.

Traphicone
quelle
3
Ich möchte, dass die Lösung os-unabhängig ist (zumindest zwischen Windows und Mac), damit der Windows-Skript-Host sie nicht erfüllt, es sei denn, es gibt eine vergleichbare Lösung für die Mac-Plattform
Jared,
5

Wenn Sie Eingabefeld wie haben

<input type="file" id="file" name="file" onchange="add(event)"/>

Sie können Dateiinhalte im BLOB-Format abrufen:

function add(event){
  var userFile = document.getElementById('file');
  userFile.src = URL.createObjectURL(event.target.files[0]);
  var data = userFile.src;
}
Radek Mezuláník
quelle
4

FSO.js umschließt die neue HTML5-Dateisystem-API, die vom W3C standardisiert wird, und bietet eine äußerst einfache Möglichkeit, aus einem lokalen Sandbox-Dateisystem zu lesen, in dieses zu schreiben oder es zu durchlaufen. Es ist asynchron, sodass die Datei-E / A die Benutzererfahrung nicht beeinträchtigt. :) :)

kwh
quelle
1
FSO.js wird derzeit von IE, Mozilla oder Safari nicht unterstützt.
Phillip Senn
2

Wenn Sie Zugriff auf das gesamte Dateisystem auf dem Client benötigen, Dateien lesen / schreiben, Ordner auf Änderungen überwachen, Anwendungen starten, Dokumente verschlüsseln oder signieren usw., schauen Sie sich bitte JSFS an.

Es ermöglicht einen sicheren und unbegrenzten Zugriff von Ihrer Webseite auf Computerressourcen auf dem Client, ohne eine Browser-Plugin-Technologie wie AcitveX oder Java Applet zu verwenden. Es muss jedoch auch eine gewisse Software installiert werden.

Um mit JSFS arbeiten zu können, sollten Sie über Grundkenntnisse in der Java- und Java EE-Entwicklung (Servlets) verfügen.

JSFS finden Sie hier: https://github.com/jsfsproject/jsfs . Es ist kostenlos und unter der GPL lizenziert

Wimix
quelle
1

Angenommen, jede Datei, die JavaScript-Code benötigt, sollte direkt vom Benutzer zugelassen werden. Entwickler berühmter Browser lassen JavaScript im Allgemeinen nicht auf Dateien zugreifen.

Die Hauptidee der Lösung ist: Der JavaScript-Code kann nicht über seine lokale URL auf die Datei zugreifen. Die Datei kann jedoch mithilfe der DataURL verwendet werden. Wenn der Benutzer eine Datei durchsucht und öffnet, sollte JavaScript die "DataURL" direkt aus HTML abrufen, anstatt die "URL" abzurufen.

Anschließend wird die DataURL mithilfe der Funktion readAsDataURL und des FileReader-Objekts in eine Datei umgewandelt. Quelle und eine vollständigere Anleitung mit einem schönen Beispiel finden Sie in:

https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=de-US&redirectslug=DOM%2FFileReader

Makan Tayebi
quelle
0

Es gibt ein (kommerzielles) Produkt, "localFS", mit dem das gesamte Dateisystem auf dem Client-Computer gelesen und geschrieben werden kann.

Eine kleine Windows-App muss installiert und eine winzige .js-Datei auf Ihrer Seite enthalten sein.

Aus Sicherheitsgründen kann der Dateisystemzugriff auf einen Ordner beschränkt und mit einem geheimen Schlüssel geschützt werden.

https://www.fathsoft.com/localfs

bewundernhodzic
quelle
-4

Wenn Sie anglejs & aspnet / mvc verwenden, um JSON-Dateien abzurufen, müssen Sie den MIME-Typ in der Webkonfiguration zulassen

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>
Mohamed.Abdo
quelle