Локальный доступ к файлам с помощью JavaScript

177

Есть ли локальные манипуляции с файлами, которые были сделаны с помощью JavaScript? Я ищу решение, которое может быть реализовано без установки, как, например, требующий Adobe AIR .

В частности, я хотел бы прочитать содержимое из файла и записать это содержимое в другой файл. На данный момент я не беспокоюсь о получении разрешений и просто предполагаю, что у меня уже есть полные разрешения для этих файлов.

Джаред
источник
1
специфичный для chrome XHR: stackoverflow.com/questions/4819060/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Ответы:

87

Если пользователь выбирает файл через <input type="file">, вы можете прочитать и обработать этот файл, используя File API .

Чтение или запись произвольных файлов не допускается. Это нарушение песочницы. Из Википедии -> Javascript -> Безопасность :

JavaScript и DOM предоставляют злоумышленникам возможность создавать сценарии для запуска на клиентском компьютере через Интернет. Авторы браузера содержат этот риск, используя два ограничения. Во-первых, сценарии выполняются в песочнице, в которой они могут выполнять только действия, связанные с Интернетом, а не задачи общего назначения, такие как создание файлов .

ОБНОВЛЕНИЕ 2016 : прямой доступ к файловой системе возможен через API-интерфейс файловой системы , который поддерживается только в Chrome и Opera и может не реализоваться другими браузерами (за исключением Edge ). Подробности см. В ответе Кевина .

Чейз Сейберт
источник
28
Черт. Это глупо, конечно. Javascript - это, предположительно, независимый от приложений язык сценариев. Не каждое приложение является веб-браузером. Я пришел сюда, потому что мне интересно, например, создавать сценарии для Photoshop. Даже если некоторые приложения не предоставляют классы доступа к файлам, имеет смысл стандартизировать их для тех приложений, где они уместны - стандартная, но дополнительная функция, поэтому опыт работы с одним приложением переносится, даже если он не универсален. То, что я изучаю в Photoshop, не будет переносимым даже на другие хосты Javascript, которые разрешают доступ к файлам.
Steve314
27
Javascript язык и делать все, что позволяет среда размещения. SpiderMonkey может делать все, что может любой другой язык. Javascript в браузере находится в песочнице.
35
Этот ответ, возможно, был правильным 3 года назад, но, конечно, он больше не правильный. Смотрите ответ @Horst Walter на HTML5. Или зайдите сюда: html5rocks.com/en/tutorials/file/dndfiles
james.garriss
@ james.garriss Да, на самом деле это тоже было не совсем правильно три года назад. Эта страница научила меня , как чтение / запись с Firefox в 2003 web.archive.org/web/20031229011919/http://www.captain.at/... (Bulit для XUL , но доступны в браузере с XPCOM) и Microsoft было сценарии оболочки javscript в стиле node.js в 1990-х годах (и FileIO, доступный в браузере с ActiveX)
original_username
Больше невозможно
SysDragon
158

Просто обновление функций HTML5 находится на http://www.html5rocks.com/en/tutorials/file/dndfiles/ . Эта превосходная статья подробно объяснит доступ к локальным файлам в JavaScript. Резюме из упомянутой статьи:

Спецификация предоставляет несколько интерфейсов для доступа к файлам из «локальной» файловой системы :

  1. Файл - отдельный файл; предоставляет информацию только для чтения, такую ​​как имя, размер файла, тип MIME и ссылку на дескриптор файла.
  2. FileList - массивоподобная последовательность объектов File. (Подумайте <input type="file" multiple>или перетащите каталог файлов с рабочего стола).
  3. Blob - позволяет разбивать файл на байтовые диапазоны.

Смотрите комментарий Пола Д. Уэйта ниже.

Хорст Уолтер
источник
7
Это не совсем настоящая файловая система, подобная той, которую мы используем с помощью плагина Java или Flash. Например, мы не можем перечислить файлы на рабочем столе пользователя, если он сам не выберет их.
Pacerier
9
Похоже, что эти API заброшены: см. W3.org/TR/file-writer-api и html5rocks.com/en/tutorials/file/filesystem
Пол Д. Уэйт
4
Осторожнее, учитывая форму W3C для того, чтобы выхватить полезные технологии. Файловая система API, реализованная только в Chrome, не продвигается. Файл апи, имеет универсальную поддержку, принимаются в качестве w3c рабочего проекта , и мы больше не можем представить себе жизнь без него. Конечно, мы все еще в браузере, и нам нужно подождать, пока пользователь принесет нам файл, но это значительно расширяет охват веб-приложений и не исчезнет в ближайшее время.
bbsimonbb
21

ОБНОВЛЕНИЕ Эта функция удалена начиная с Firefox 17 (см. Https://bugzilla.mozilla.org/show_bug.cgi?id=546848 ).


В Firefox вы (программист) можете сделать это из файла JavaScript:

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

и вам (пользователю браузера) будет предложено разрешить доступ. (для Firefox вам просто нужно делать это один раз при каждом запуске браузера)

Если пользователь браузера - это кто-то другой, он должен дать разрешение.

Джейсон С
источник
6
Это дает ошибку, что она устарела, и вы можете делать это только в расширении, а не на веб-сайте javascript
Esailija
4
как показывает эта ссылка, эта функция была удалена в более поздних версиях Firefox. support.mozilla.org/en-US/questions/944433
Макан Тайеби,
3
о, это отстой. Я получаю безопасность и все такое, но нам нужен способ предоставления доверия для локального запуска наших собственных файлов javascript.
Джейсон С
конечно. и я еще не нашел другого способа сделать это.
Макан Тайеби
2
Пожалуйста, обновите ответ, чтобы показать, что он устарел. Спасибо.
jpaugh
20

Как упоминалось ранее, FileSystem и File API, вместе с FileWriter API, могут использоваться для чтения и записи файлов из контекста вкладки / окна браузера на клиентский компьютер.

Есть несколько вещей, относящихся к API-интерфейсам FileSystem и FileWriter, о которых вы должны знать, некоторые из которых были упомянуты, но стоит повторить:

  • Реализации API в настоящее время существуют только в браузерах на основе Chromium (Chrome & Opera)
  • 24 апреля 2014 года оба API были сняты со стандартного стандарта W3C и на данный момент являются собственностью.
  • Удаление (теперь проприетарных) API-интерфейсов из реализации браузеров в будущем возможно
  • Для хранения файлов, созданных с помощью API, используется песочница (место на диске, вне которого файлы не могут оказывать никакого влияния)
  • Виртуальная файловая система (структура каталогов , которая не обязательно существует на диске в той же форме , что делает , когда доступ из браузера) используется представляют файлы , созданные с помощью API -

Вот простые примеры того, как API-интерфейсы, прямо и косвенно, используются для выполнения этих задач:

BakedGoods *

Написать файл:

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

Читать файл:

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

Использование сырых API File, FileWriter и FileSystem

Написать файл:

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

Читать файл:

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

Хотя API FileSystem и FileWriter более не соответствуют стандартам, их использование в некоторых случаях может быть оправдано, на мой взгляд, потому что:

  • Возобновление интереса со стороны не реализующих поставщиков браузеров может вернуть их обратно
  • Проникновение на рынок внедряющих браузеров (на основе хрома)
  • Google (основной вкладчик в Chromium) не дал и API-интерфейсы с истекшим сроком эксплуатации

Однако, «некоторые случаи» охватывают ваши собственные, решать вам.

* BakedGoods поддерживается здесь только этим парнем :)

Kevin
источник
8

NW.js позволяет создавать настольные приложения с использованием Javascript без всех ограничений безопасности, обычно устанавливаемых в браузере. Таким образом, вы можете запускать исполняемые файлы с функцией или создавать / редактировать / читать / записывать / удалять файлы. Вы можете получить доступ к аппаратным средствам, таким как текущее использование процессора или общее количество оперативной памяти в использовании, и т. Д.

С его помощью вы можете создать приложение для Windows, Linux или Mac, которое не требует установки.

Jaredcheeda
источник
1
Также возможно получить доступ к локальным файлам с помощью Electron , который является аналогичной средой для настольных приложений JavaScript.
Андерсон Грин
6

Если вы развертываете в Windows, Windows Script Host предлагает очень полезный JScript API для файловой системы и других локальных ресурсов. Однако включение сценариев WSH в локальное веб-приложение может оказаться не таким элегантным, как хотелось бы.

Traphicone
источник
3
Мне бы хотелось, чтобы решение было независимым от ОС (по крайней мере, между Windows и Mac), поэтому хост сценариев Windows не удовлетворяет его, если не существует сопоставимого решения для платформы Mac
Jared
5

Если у вас есть поле ввода, как

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

Вы можете получить содержимое файла в формате BLOB:

function add(event){
  var userFile = document.getElementById('file');
  userFile.src = URL.createObjectURL(event.target.files[0]);
  var data = userFile.src;
}
Радек Мезуланик
источник
4

FSO.js оборачивает новый API-интерфейс файловой системы HTML5, который стандартизируется W3C, и обеспечивает чрезвычайно простой способ чтения, записи или обхода локальной изолированной файловой системы. Он асинхронный, поэтому файловый ввод-вывод не будет мешать работе пользователя. :)

киловатт-часов
источник
1
FSO.js в настоящее время не поддерживается IE, Mozilla или Safari.
Филипп Сенн
2

Если вам нужен доступ ко всей файловой системе на клиенте, чтение / запись файлов, просмотр папок на предмет изменений, запуск приложений, шифрование или подпись документов и т. Д., Пожалуйста, посмотрите на JSFS.

Он обеспечивает безопасный и неограниченный доступ с вашей веб-страницы к ресурсам компьютера на клиенте без использования технологии плагинов для браузера, такой как AcitveX или Java Applet. Тем не менее, мир программного обеспечения также должен быть установлен.

Для работы с JSFS у вас должны быть базовые знания по разработке Java и Java EE (Servlets).

Пожалуйста, найдите JSFS здесь: https://github.com/jsfsproject/jsfs . Это бесплатно и под лицензией GPL

wimix
источник
1

Предполагая, что любой файл, который может понадобиться коду JavaScript, должен быть разрешен непосредственно пользователем. Создатели известных браузеров вообще не разрешают JavaScript доступ к файлам.

Основная идея решения заключается в следующем: код JavaScript не может получить доступ к файлу, имея его локальный URL. Но он может использовать файл, имея свой DataURL: поэтому, если пользователь просматривает файл и открывает его, JavaScript должен получить «DataURL» непосредственно из HTML, а не «URL».

Затем он превращает DataURL в файл, используя функцию readAsDataURL и объект FileReader. Источник и более полное руководство с хорошим примером находятся в:

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

Макан Тайеби
источник
0

Существует (коммерческий) продукт, localFS, который можно использовать для чтения и записи всей файловой системы на клиентском компьютере.

Небольшое приложение для Windows должно быть установлено, а крошечный файл .js включен в вашу страницу

В качестве функции безопасности доступ к файловой системе может быть ограничен одной папкой и защищен секретным ключом.

https://www.fathsoft.com/localfs

admirhodzic
источник
0

Я только упоминаю это, поскольку никто не упомянул это. Я не знаю ни одного языка программирования, который позволял бы манипулировать базовой файловой системой. Все языки программирования полагаются на прерывания ОС, чтобы на самом деле добиться этого. JavaScript, который запускается в браузере, имеет только браузерные «прерывания» для работы, которые обычно не предоставляют доступ к файловой системе, если браузер не был реализован для поддержки таких прерываний.

При этом очевидный способ получить доступ к файловой системе с использованием JavaScript - это использовать Node.js, который имеет возможность напрямую взаимодействовать с базовой ОС.

apokryfos
источник
-4

если вы используете angularjs & aspnet / mvc, для извлечения файлов json вы должны разрешить тип mime в веб-конфигурации

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>
Mohamed.Abdo
источник