Потоковая передача сгенерированного на стороне клиента ответа в виде загрузки без сервис-воркера - PullRequest
0 голосов
/ 13 июля 2020

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

Обычным методом было бы создание Blob, а затем создание URL-адреса объекта для него:

const blob = new Blob([chunks], {type: 'application/example'});
linkEl.href = URL.createObjectUrl(blob);

Это работает, но не очень эффективно, так как может быстро исчерпать всю доступную память, так как полученный файл должен оставаться в памяти.

Лучше бы метод включить потоковую передачу. Примерно так:

const outputStream = new WritableStream();
linkEl.href = URL.createObjectUrl(outputStream);
while (let chunk = await getChunk()) {
  outputStream.write();
}
outputStream.end();

Есть ли прямой способ сделать это сегодня?

Единственный метод, который я видел для потоковой передачи, подобный этому, - использовать Service Worker. К сожалению, во многих ситуациях Service Worker недоступен. Режимы конфиденциальности могут обходить всех сервисных работников. Жесткое обновление страницы отключает их. Открытие инструментов браузера может сбросить состояние сервис-воркера. Рабочий может быть отключен в любой момент, и попытки поддержать его с помощью обмена сообщениями не гарантируются. Все эти хаки были реализованы здесь в отличном проекте: https://github.com/jimmywarting/StreamSaver.js Но, в конце концов, это ненадежно из-за ограничений браузера.

Существует ли подходящий API для потоковой передачи "загрузки" на стороне клиента без использования сервис-воркера?

1 Ответ

1 голос
/ 14 июля 2020

Определен один ... Собственная файловая система .

Это все еще ранний черновик, и только Chrome начал его реализовывать, но вы уже можете попробовать это после включения флага chrome://flags/#native-file-system-api.

Вас особенно заинтересует интерфейс FileSystemWritableFileStream , который позволит записывать на диск после того, как пользователь выберет, где вы можете возиться с их data; -)

Код не в реальном времени, так как «Изолированные документы не могут отображать средство выбора файлов». ...

onclick = async () => {

if( !("chooseFileSystemEntries" in self) ) {
  throw new Error( "unsupported browser" );
}

const handle = await chooseFileSystemEntries( { type:'save-file' } );
const filestream = await handle.createWritable();
const writer = await filestream.getWriter();
// here we have a WritableStream, with direct access to the user's disk
await writer.write( "hello" );
await writer.write( " world" );
writer.close();

};

Вот live plnkr , который необходимо запускать в оконном режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...