Добавить в корзинуПозвонить
Найти в Дзене

Помню, в одном из банков, которые я сменил за последние несколько лет, в настройках была опция выбрать папку для сохранения файлов

Пользователь один раз выбирал директорию, а дальше все выгрузки сохранялись туда без стандартного диалога выбора файла. Тогда я и решил разобраться, как браузер вообще может работать с локальной файловой системой. Долго откладывал, но наконец добрался до File System Access API. Это API позволяет сайту работать с локальными файлами и папками, но только после явного выбора пользователя. Например, можно открыть папку и пройтись по её содержимому: const directoryHandle = await window.showDirectoryPicker({ mode: 'read', }); for await (const [name, handle] of directoryHandle.entries()) { console.log(name, handle.kind); } handle.kind будет file или directory. Можно попросить пользователя выбрать конкретный файл и прочитать его: const [fileHandle] = await window.showOpenFilePicker({ types: [ { description: 'Text files', accept: { 'text/plain': ['.txt', '.md', '.json'], }, }, ], }); const file = await fileHandle.getFile(); const content = await file.text(); console.log(content); А мо

Помню, в одном из банков, которые я сменил за последние несколько лет, в настройках была опция выбрать папку для сохранения файлов.

Пользователь один раз выбирал директорию, а дальше все выгрузки сохранялись туда без стандартного диалога выбора файла.

Тогда я и решил разобраться, как браузер вообще может работать с локальной файловой системой. Долго откладывал, но наконец добрался до File System Access API.

Это API позволяет сайту работать с локальными файлами и папками, но только после явного выбора пользователя.

Например, можно открыть папку и пройтись по её содержимому:

const directoryHandle = await window.showDirectoryPicker({

mode: 'read',

});

for await (const [name, handle] of directoryHandle.entries()) {

console.log(name, handle.kind);

}

handle.kind будет file или directory.

Можно попросить пользователя выбрать конкретный файл и прочитать его:

const [fileHandle] = await window.showOpenFilePicker({

types: [

{

description: 'Text files',

accept: {

'text/plain': ['.txt', '.md', '.json'],

},

},

],

});

const file = await fileHandle.getFile();

const content = await file.text();

console.log(content);

А можно создать новый файл и записать в него данные:

const fileHandle = await window.showSaveFilePicker({

suggestedName: 'notes.md',

types: [

{

description: 'Markdown',

accept: {

'text/markdown': ['.md'],

},

},

],

});

const writable = await fileHandle.createWritable();

await writable.write('# Hello from browser');

await writable.close();

🔐 С безопасностью всё завязано на явное действие пользователя. Сайт не может просто так взять и открыть произвольную папку на диске.

Более того, браузер может не дать выбрать слишком широкие или чувствительные директории — например, Downloads или Desktop. Там обычно лежит всё подряд, и отдать сайту доступ к такой папке слишком легко случайно.

Запись тоже требует отдельного разрешения. Плюс API работает только в secure context: HTTPS или localhost.

Конечно, в продакшене использовать всё это врядли получится. Функции всё ещё экспериментальные и нормально поддерживаются в основном Chromium-браузерами, поэтому на телефоне не заведётся.

🧪 Собрал небольшое демо, где можно потыкать это в браузере.

https://cherkashin.dev/demos/file-system-access-demo/

Ставьте:

👍 — если знали про File System Access API

❤️ — если узнали что-то новое

😱 — если страшно давать браузеру доступ к файлам

#frontend