Accès aux fichiers locaux avec JavaScript

177

Existe-t-il une manipulation de fichiers locaux effectuée avec JavaScript? Je recherche une solution qui peut être réalisée sans encombrement d'installation, comme en exigeant Adobe AIR .

Plus précisément, j'aimerais lire le contenu d'un fichier et écrire ce contenu dans un autre fichier. À ce stade, je ne suis pas inquiet d'obtenir des autorisations et je suppose simplement que j'ai déjà toutes les autorisations sur ces fichiers.

Jared
la source
1
chrome XHR spécifique: stackoverflow.com/questions/4819060/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

87

Si l'utilisateur sélectionne un fichier via <input type="file">, vous pouvez lire et traiter ce fichier à l'aide de l' API de fichier .

La lecture ou l'écriture de fichiers arbitraires n'est pas autorisée par conception. C'est une violation du bac à sable. Depuis Wikipedia -> Javascript -> Sécurité :

JavaScript et le DOM permettent aux auteurs malveillants de fournir des scripts à exécuter sur un ordinateur client via le Web. Les auteurs de navigateurs contiennent ce risque en utilisant deux restrictions. Tout d'abord, les scripts s'exécutent dans un bac à sable dans lequel ils ne peuvent effectuer que des actions liées au Web, pas des tâches de programmation à usage général telles que la création de fichiers .

MISE À JOUR 2016 : L'accès direct au système de fichiers est possible via l' API Filesystem , qui n'est prise en charge que par Chrome et Opera et peut ne pas être implémentée par d'autres navigateurs (à l' exception d'Edge ). Pour plus de détails, voir la réponse de Kevin .

Chase Seibert
la source
28
Zut. C'est stupide, bien sûr. Javascript est censé être un langage de script indépendant des applications. Toutes les applications ne sont pas un navigateur Web. Je suis venu ici parce que je suis intéressé par les scripts Photoshop, par exemple. Même si certaines applications ne fournissent pas de classes d'accès aux fichiers, il est logique de les standardiser pour ces applications là où elles sont appropriées - une fonctionnalité standard mais facultative, de sorte que l'expérience d'une application est transférable même si elle n'est pas universellement applicable. Ce que j'apprends dans Photoshop ne sera pas portable, même sur d'autres hôtes Javascript qui permettent l'accès aux fichiers.
Steve314
27
Javascript est le langage et faites tout ce que l'environnement d'hébergement lui permet. SpiderMonkey peut faire tout ce que n'importe quelle autre langue peut faire. Javascript dans le navigateur est en bac à sable.
35
Cette réponse était peut-être correcte il y a 3 ans, mais elle ne l'est certainement plus. Voir la réponse de @Horst Walter sur HTML5. Ou allez ici: html5rocks.com/en/tutorials/file/dndfiles
james.garriss
@ james.garriss Ouais, en fait ce n'était pas super correct il y a trois ans non plus. Cette page m'a appris à lire / écrire avec Firefox en 2003 web.archive.org/web/20031229011919/http ://www.captain.at/... (bulit pour XUL mais disponible dans le navigateur avec XpCom) et Microsoft avait Node.js style script shell javscript dans les années 1990 (et FileIO disponible dans le navigateur avec ActiveX)
original_username
Plus
158

Une simple mise à jour des fonctionnalités HTML5 est disponible sur http://www.html5rocks.com/en/tutorials/file/dndfiles/ . Cet excellent article vous expliquera en détail l'accès aux fichiers locaux en JavaScript. Résumé de l'article mentionné:

La spécification fournit plusieurs interfaces pour accéder aux fichiers à partir d'un système de fichiers `` local '' :

  1. Fichier - un fichier individuel; fournit des informations en lecture seule telles que le nom, la taille du fichier, le type MIME et une référence au descripteur de fichier.
  2. FileList - une séquence de type tableau d'objets File. (Pensez <input type="file" multiple>ou faites glisser un répertoire de fichiers depuis le bureau).
  3. Blob - Permet de découper un fichier en plages d'octets.

Voir le commentaire de Paul D. Waite ci-dessous.

Horst Walter
la source
7
Ce n'est pas exactement un vrai système de fichiers comme ce que nous avons en utilisant le plugin Java ou Flash. Par exemple, nous ne pouvons pas lister les fichiers sur le bureau de l'utilisateur à moins qu'il ne les sélectionne d'abord lui-même.
Pacerier
9
On dirait que ces API sont en cours d'abandon: voir w3.org/TR/file-writer-api et html5rocks.com/en/tutorials/file/filesystem
Paul D. Waite
4
Attention là, étant donné la forme du W3C pour arracher la technologie utile. L'API du système de fichiers, implémentée uniquement dans Chrome, ne va pas de l'avant. Le fichier api, a un support universel , est accepté comme un brouillon de travail w3c et nous ne pouvons plus imaginer la vie sans lui. Bien sûr, nous sommes toujours dans un navigateur et nous devons attendre que l'utilisateur nous apporte le fichier, mais cela étend considérablement la portée des applications Web et ne disparaîtra pas de sitôt.
bbsimonbb
21

MISE À JOUR Cette fonctionnalité est supprimée depuis Firefox 17 (voir https://bugzilla.mozilla.org/show_bug.cgi?id=546848 ).


Sur Firefox, vous (le programmeur) pouvez le faire à partir d'un fichier JavaScript:

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

et vous (l'utilisateur du navigateur) serez invité à autoriser l'accès. (pour Firefox, il vous suffit de le faire une fois à chaque démarrage du navigateur)

Si l'utilisateur du navigateur est quelqu'un d'autre, il doit accorder l'autorisation.

Jason S
la source
6
Cela donne une erreur indiquant qu'il est obsolète et que vous ne pouvez le faire que dans une extension, pas sur un site Web javascript
Esailija
4
comme le montre ce lien, cette fonctionnalité a été supprimée dans les versions ultérieures de Firefox. support.mozilla.org/en-US/questions/944433
Makan Tayebi
3
oh, ça craint. J'obtiens la sécurité et tout ça, mais nous avons besoin d'un moyen d'accorder la confiance pour exécuter nos propres fichiers javascript localement.
Jason S
sûr. et je n'ai pas encore trouvé d'autre moyen de le faire.
Makan Tayebi
2
Veuillez mettre à jour la réponse pour indiquer qu'elle est obsolète. Merci.
jpaugh
20

Comme mentionné précédemment, les API FileSystem et File , ainsi que l' API FileWriter , peuvent être utilisées pour lire et écrire des fichiers à partir du contexte d'un onglet / fenêtre de navigateur sur un ordinateur client.

Il y a plusieurs choses concernant les API FileSystem et FileWriter dont vous devez être conscient, dont certaines ont été mentionnées, mais qu'il convient de répéter:

  • Les implémentations des API n'existent actuellement que dans les navigateurs basés sur Chromium (Chrome et Opera)
  • Les deux API ont été retirées de la piste des normes du W3C le 24 avril 2014 et sont désormais propriétaires
  • La suppression des API (désormais propriétaires) de la mise en œuvre des navigateurs à l'avenir est une possibilité
  • Un bac à sable (un emplacement sur le disque en dehors duquel les fichiers ne peuvent produire aucun effet) est utilisé pour stocker les fichiers créés avec les API
  • Un système de fichiers virtuel (une structure de répertoires qui n'existe pas nécessairement sur le disque sous la même forme que lors de l'accès à partir du navigateur) est utilisé pour représenter les fichiers créés avec les API

Voici des exemples simples de la façon dont les API sont utilisées, directement et indirectement, en tandem pour faire ces choses:

Produits de boulangerie *

Ecrire le fichier:

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

Lire le fichier:

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

Utilisation des API Raw File, FileWriter et FileSystem

Ecrire le fichier:

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);

Lire le fichier:

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);

Bien que les API FileSystem et FileWriter ne soient plus sur la voie des normes, leur utilisation peut être justifiée dans certains cas, à mon avis, car:

  • L'intérêt renouvelé des fournisseurs de navigateurs non implémentés peut les remettre directement
  • La pénétration du marché de la mise en œuvre de navigateurs (à base de chrome) est élevée
  • Google (le principal contributeur de Chromium) n'a pas donné de date de fin de vie aux API

Cependant, si «certains cas» englobe le vôtre, c'est à vous de décider.

* BakedGoods est maintenu par nul autre que ce gars ici :)

Kevin
la source
8

NW.js vous permet de créer des applications de bureau en utilisant Javascript sans toutes les restrictions de sécurité généralement placées sur le navigateur. Ainsi, vous pouvez exécuter des exécutables avec une fonction, ou créer / modifier / lire / écrire / supprimer des fichiers. Vous pouvez accéder au matériel, comme l'utilisation actuelle du processeur ou la quantité totale de RAM utilisée, etc.

Vous pouvez créer une application de bureau Windows, Linux ou Mac qui ne nécessite aucune installation.

Jaredcheeda
la source
1
Il est également possible d'accéder aux fichiers locaux à l'aide d' Electron , qui est un cadre similaire pour les applications de bureau JavaScript.
Anderson Green
6

Si vous déployez sur Windows, l' hôte de script Windows offre une API JScript très utile au système de fichiers et à d'autres ressources locales. Cependant, l'intégration de scripts WSH dans une application Web locale n'est peut-être pas aussi élégante que vous le souhaiteriez.

Traphicone
la source
3
J'aimerais que la solution soit indépendante du système d'exploitation (au moins entre Windows et Mac), de sorte que l'hôte de script Windows ne le satisfait pas, à moins qu'il n'y ait une solution comparable pour la plate
Jared
5

Si vous avez un champ de saisie comme

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

Vous pouvez accéder au contenu du fichier au format BLOB:

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

FSO.js encapsule la nouvelle API HTML5 FileSystem qui est normalisée par le W3C et fournit un moyen extrêmement simple de lire, d'écrire ou de parcourir un système de fichiers local en bac à sable. Il est asynchrone, donc les E / S de fichier n'interféreront pas avec l'expérience utilisateur. :)

kwh
la source
1
FSO.js n'est actuellement pas pris en charge par IE, Mozilla ou Safari.
Phillip Senn
2

Si vous avez besoin d'accéder à l'ensemble du système de fichiers sur le client, lire / écrire des fichiers, surveiller les dossiers pour les changements, démarrer des applications, crypter ou signer des documents, etc., veuillez consulter JSFS.

Il permet un accès sécurisé et illimité depuis votre page Web aux ressources informatiques sur le client sans utiliser une technologie de plugin de navigateur comme AcitveX ou Java Applet. Cependant, une paix de logiciels doit également être installée.

Afin de travailler avec JSFS, vous devez avoir des connaissances de base en développement Java et Java EE (Servlets).

Veuillez trouver JSFS ici: https://github.com/jsfsproject/jsfs . C'est gratuit et sous licence GPL

wimix
la source
1

En supposant que tout fichier dont le code JavaScript pourrait avoir besoin, devrait être autorisé directement par l'utilisateur. Les créateurs de navigateurs célèbres ne laissent généralement pas JavaScript accéder aux fichiers.

L'idée principale de la solution est: le code JavaScript ne peut pas accéder au fichier en ayant son URL locale. Mais il peut utiliser le fichier en ayant son DataURL: donc si l'utilisateur parcourt un fichier et l'ouvre, JavaScript devrait obtenir le "DataURL" directement à partir du HTML au lieu d'obtenir "URL".

Ensuite, il transforme le DataURL en un fichier, en utilisant la fonction readAsDataURL et l'objet FileReader. La source et un guide plus complet avec un bel exemple se trouvent dans:

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

Makan Tayebi
la source
0

Il existe un produit (commercial), "localFS", qui peut être utilisé pour lire et écrire tout le système de fichiers sur l'ordinateur client.

Une petite application Windows doit être installée et un petit fichier .js doit être inclus dans votre page.

En tant que fonction de sécurité, l'accès au système de fichiers peut être limité à un dossier et protégé par une clé secrète.

https://www.fathsoft.com/localfs

admirhodzique
la source
0

Je ne mentionne cela que car personne ne l'a mentionné. Il n'y a pas de langage de programmation que je connaisse qui permette la manipulation du système de fichiers sous-jacent. Tous les langages de programmation s'appuient sur les interruptions du système d'exploitation pour accomplir ces tâches. JavaScript qui s'exécute dans le navigateur n'a que des "interruptions" de navigateur pour fonctionner, ce qui n'accorde généralement pas l'accès au système de fichiers à moins que le navigateur n'ait été implémenté pour prendre en charge de telles interruptions.

Cela étant dit, la manière la plus évidente d'accéder au système de fichiers à l'aide de JavaScript est d'utiliser Node.js qui a la capacité d'interagir directement avec le système d'exploitation sous-jacent.

apokryfos
la source
-4

si vous utilisez angularjs & aspnet / mvc, pour récupérer des fichiers json, vous devez autoriser le type mime dans la configuration web

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