Acceso a archivos locales con JavaScript

177

¿Hay manipulación local de archivos que se ha hecho con JavaScript? Estoy buscando una solución que se pueda lograr sin necesidad de instalar, como Adobe AIR .

Específicamente, me gustaría leer el contenido de un archivo y escribir ese contenido en otro archivo. En este punto, no estoy preocupado por obtener permisos y solo asumo que ya tengo permisos completos para estos archivos.

Jared
fuente
1
Chrome XHR específico: stackoverflow.com/questions/4819060/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

87

Si el usuario selecciona un archivo mediante <input type="file">, puede leer y procesar ese archivo utilizando la API de archivo .

Leer o escribir archivos arbitrarios no está permitido por diseño. Es una violación de la caja de arena. De Wikipedia -> Javascript -> Seguridad :

JavaScript y el DOM brindan la posibilidad de que los autores maliciosos entreguen scripts para que se ejecuten en una computadora cliente a través de la web. Los autores del navegador contienen este riesgo usando dos restricciones. Primero, los scripts se ejecutan en un entorno limitado en el que solo pueden realizar acciones relacionadas con la web, no tareas de programación de propósito general como la creación de archivos .

ACTUALIZACIÓN 2016 : el acceso al sistema de archivos directamente es posible a través de la API del sistema de archivos , que solo es compatible con Chrome y Opera y puede que no sea implementado por otros navegadores (con la excepción de Edge ). Para más detalles vea la respuesta de Kevin .

Chase Seibert
fuente
28
Maldición. Esto es estúpido, por supuesto. Se supone que Javascript es un lenguaje de script independiente de la aplicación. No todas las aplicaciones son navegadores web. Vine aquí porque estoy interesado en crear secuencias de comandos de Photoshop, por ejemplo. Incluso si algunas aplicaciones no proporcionan clases de acceso a archivos, tiene sentido estandarizarlas para aquellas aplicaciones donde son apropiadas, una característica estándar pero opcional, por lo que la experiencia de una aplicación es transferible incluso si no es universalmente aplicable. Lo que aprendo en Photoshop no será portátil incluso para otros hosts Javascript que permiten el acceso a archivos.
Steve314
27
Javascript el idioma y haga lo que el entorno de alojamiento le permita hacer. SpiderMonkey puede hacer cualquier cosa que cualquier otro idioma pueda hacer. Javascript en el navegador está protegido.
35
Esta respuesta podría haber sido correcta hace 3 años, pero ciertamente ya no es correcta. Vea la respuesta de @Horst Walter en HTML5. O vaya aquí: html5rocks.com/en/tutorials/file/dndfiles
james.garriss del
@ james.garriss Sí, en realidad tampoco fue súper correcto hace tres años. Esta página me enseñó a leer / escribir con Firefox en 2003 web.archive.org/web/20031229011919/http://www.captain.at/… (bulit para XUL pero disponible en el navegador con XpCom) y Microsoft tenía Script de shell javscript estilo node.js en la década de 1990 (y FileIO disponible en el navegador con ActiveX)
original
Ya no es posible
SysDragon
158

Solo hay una actualización de las características HTML5 en http://www.html5rocks.com/en/tutorials/file/dndfiles/ . Este excelente artículo explicará en detalle el acceso a archivos locales en JavaScript. Resumen del artículo mencionado:

La especificación proporciona varias interfaces para acceder a archivos desde un sistema de archivos 'local' :

  1. Archivo: un archivo individual; proporciona información de solo lectura, como nombre, tamaño de archivo, tipo MIME y una referencia al identificador de archivo.
  2. FileList: una secuencia tipo matriz de objetos File. (Piense <input type="file" multiple>o arrastre un directorio de archivos desde el escritorio).
  3. Blob: permite cortar un archivo en rangos de bytes.

Vea el comentario de Paul D. Waite a continuación.

Horst Walter
fuente
77
No es exactamente un verdadero sistema de archivos como el que tenemos usando el complemento Java o Flash. Por ejemplo, no podemos enumerar los archivos en el escritorio del usuario a menos que primero los seleccione él mismo.
Pacerier
9
Parece que estas API están siendo abandonadas: ver w3.org/TR/file-writer-api y html5rocks.com/en/tutorials/file/filesystem
Paul D. Waite
44
Cuidado allí, dada la forma del W3C para arrebatar tecnología útil. La API del sistema de archivos, solo implementada en Chrome, no avanza. El archivo api, tiene soporte universal , es aceptado como un borrador de trabajo de w3c y ya no podemos imaginar la vida sin él. Por supuesto, todavía estamos en un navegador, y tenemos que esperar hasta que el usuario nos traiga el archivo, pero esto extiende drásticamente el alcance de las aplicaciones web y no desaparecerá pronto.
bbsimonbb
21

ACTUALIZACIÓN Esta característica se elimina desde Firefox 17 (consulte https://bugzilla.mozilla.org/show_bug.cgi?id=546848 ).


En Firefox, usted (el programador) puede hacer esto desde un archivo JavaScript:

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

y se le pedirá a usted (el usuario del navegador) que permita el acceso. (para Firefox solo necesita hacer esto una vez cada vez que se inicia el navegador)

Si el usuario del navegador es otra persona, debe otorgar permiso.

Jason S
fuente
66
Esto da un error de que está en desuso y solo puede hacerlo en una extensión, no en el sitio web javascript
Esailija
44
Como muestra este enlace, esta característica se ha eliminado en versiones posteriores de Firefox. support.mozilla.org/en-US/questions/944433
Makan Tayebi
3
oh, eso apesta Tengo seguridad y todo eso, pero necesitamos una forma de otorgar confianza para ejecutar nuestros propios archivos javascript localmente.
Jason S
Por supuesto. y aún no he encontrado otra forma de hacerlo.
Makan Tayebi
2
Actualice la respuesta para mostrar que está en desuso. Gracias.
jpaugh
20

Como se mencionó anteriormente, las API FileSystem y File , junto con FileWriter API , se pueden usar para leer y escribir archivos desde el contexto de una pestaña / ventana del navegador a una máquina cliente.

Debe tener en cuenta varias cosas relacionadas con las API FileSystem y FileWriter, algunas de las cuales se mencionaron, pero vale la pena repetir:

  • Las implementaciones de las API actualmente solo existen en los navegadores basados ​​en Chromium (Chrome & Opera)
  • Ambas API fueron retiradas de la pista de estándares del W3C el 24 de abril de 2014, y a partir de ahora son propietarias
  • La eliminación de las API (ahora propietarias) de la implementación de navegadores en el futuro es una posibilidad
  • Se utiliza una caja de arena (una ubicación en el disco fuera de la cual los archivos no pueden producir ningún efecto) para almacenar los archivos creados con las API
  • Se utiliza un sistema de archivos virtual (una estructura de directorio que no existe necesariamente en el disco en la misma forma que cuando se accede desde el navegador) representa los archivos creados con las API

Aquí hay ejemplos simples de cómo se usan las API, directa e indirectamente, en conjunto para hacer estas cosas:

Productos horneados *

Escribir archivo:

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

Leer archivo:

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

Uso de las API de File, FileWriter y FileSystem sin formato

Escribir archivo:

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

Leer archivo:

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

Aunque las API FileSystem y FileWriter ya no están en la pista de los estándares, su uso puede justificarse en algunos casos, en mi opinión, porque:

  • El renovado interés de los proveedores de navegadores que no se implementan puede colocarlos nuevamente en él.
  • La penetración en el mercado de la implementación de navegadores (basados ​​en cromo) es alta
  • Google (el principal contribuyente a Chromium) no ha dado una fecha de finalización de vida a las API

Sin embargo, si "algunos casos" abarca los suyos, es decisión suya.

* BakedGoods es mantenido por nada menos que este tipo aquí :)

Kevin
fuente
7

NW.js le permite crear aplicaciones de escritorio usando Javascript sin todas las restricciones de seguridad que generalmente se colocan en el navegador. Por lo tanto, puede ejecutar ejecutables con una función o crear / editar / leer / escribir / eliminar archivos. Puede acceder al hardware, como el uso actual de la CPU o el ram total en uso, etc.

Puede crear una aplicación de escritorio de Windows, Linux o Mac con ella que no requiera instalación.

Aquí hay un marco para NW.js, la GUI universal:

Jaredcheeda
fuente
1
También es posible acceder a archivos locales usando Electron , que es un marco similar para aplicaciones de escritorio JavaScript.
Anderson Green
6

Si está implementando en Windows, Windows Script Host ofrece una API JScript muy útil para el sistema de archivos y otros recursos locales. Sin embargo, incorporar scripts WSH en una aplicación web local puede no ser tan elegante como desearía.

Traficona
fuente
3
Me gustaría que la solución sea independiente del sistema operativo (al menos entre Windows y Mac), para que el host de script de Windows no lo satisfaga, a menos que haya una solución comparable para la plataforma Mac
Jared
5

Si tienes un campo de entrada como

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

Puede acceder al contenido del archivo en formato 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
fuente
4

FSO.js envuelve la nueva API HTML5 FileSystem que está siendo estandarizada por el W3C y proporciona una forma extremadamente fácil de leer, escribir o atravesar un sistema de archivos de espacio aislado local. Es asíncrono, por lo que la E / S de archivo no interferirá con la experiencia del usuario. :)

kwh
fuente
1
FSO.js no es compatible actualmente con IE, Mozilla o Safari.
Phillip Senn
2

Si necesita acceso a todo el sistema de archivos en el cliente, leer / escribir archivos, ver carpetas para cambios, iniciar aplicaciones, cifrar o firmar documentos, etc., eche un vistazo a JSFS.

Permite el acceso seguro e ilimitado desde su página web a los recursos de la computadora en el cliente sin usar una tecnología de complemento del navegador como AcitveX o Java Applet. Sin embargo, también debe instalarse un software tranquilo.

Para trabajar con JSFS, debe tener conocimientos básicos sobre el desarrollo de Java y Java EE (Servlets).

Encuentre JSFS aquí: https://github.com/jsfsproject/jsfs . Es gratis y con licencia bajo GPL

wimix
fuente
1

Asumiendo que cualquier archivo que pueda necesitar el código JavaScript, debe ser permitido directamente por el usuario. Los creadores de navegadores famosos no permiten que JavaScript acceda a los archivos en general.

La idea principal de la solución es: el código JavaScript no puede acceder al archivo al tener su URL local. Pero puede usar el archivo al tener su DataURL: así que si el usuario navega por un archivo y lo abre, JavaScript debería obtener el "DataURL" directamente del HTML en lugar de obtener el "URL".

Luego convierte el DataURL en un archivo, utilizando la función readAsDataURL y el objeto FileReader. La fuente y una guía más completa con un buen ejemplo están en:

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

Makan Tayebi
fuente
0

Hay un producto (comercial), "localFS", que se puede usar para leer y escribir todo el sistema de archivos en la computadora cliente.

Se debe instalar una pequeña aplicación de Windows y se debe incluir un pequeño archivo .js en su página.

Como característica de seguridad, el acceso al sistema de archivos puede limitarse a una carpeta y protegerse con una clave secreta.

https://www.fathsoft.com/localfs

admirhodzic
fuente
-4

si está utilizando angularjs y aspnet / mvc, para recuperar archivos json, debe permitir el tipo mime en la configuración web

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