Чем отдавать файл из браузера (js)

 Публичный пост

Собственно столкнулся с такой проблемой, надо в браузере при помощи js обрабатывать полученный от пользователя файл и отдавать назад.

С читать и обрабатывать файл все хорошо и понятно. Спасибо file-reader за это.

Но вот с отдачей обратно какая-то чехарда. Попробовал

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

Может есть еще какие-то варианты? Или может как-то более прямо из браузера можно делать? В API посмотрел нативное там какой-то бешенный зоопарк про запись файлов разной степени не рабочести.

Собственно вопрос. Как писать и отдавать файл пользователю?

11 комментариев 👇

Начни поиски отсюда https://developer.mozilla.org/en-US/docs/Web/API/Blob

Алгорит будет примерно такой:

  1. Создаешь blob из своего контента
  2. Создаешь ссылку, даешь ей url, как object url из блоба, ставишь атрибут download, в значение ставишь имя файла, которое хочешь получить
  3. Вставляешь ссылку в dom и симулируешь клик
  4. Подчищаешь за собой (удаляешь object url, ссылку из dom)
function download(data, fileName) {
  const link = document.createElement('a');
  link.style = "display: none;";
  document.body.appendChild(link);

  const json = JSON.stringify(data, null, 2);
  const blob = new Blob([json], {type: 'octet/stram'});
  const url = window.URL.createObjectURL(blob);

  link.href = url;
  link.download = fileName;
  link.click();

  window.URL.revokeObjectURL(url);
  link.remove();
}

download({hello: 'world'}, 'my.json');

Вот накидал за пару минут демку. Не продакшен реди, но работает. Дальше модифиируй под свои нужды

  Развернуть 1 комментарий

@Vita, ну вот file-server работает через это, но там есть Max Blob Size и тут к нам приходит файл больше 1гига и ой.

  Развернуть 1 комментарий

@norguhtar, Вы делаете что странное. Не надо так) Но если очень надо, то ищите способы разбить на чанки или работать с File. Там все будет сложнее, но больше смогу сказать только погрузивщись в контект задачи

  Развернуть 1 комментарий

@Vita, отож. Контекст довольно простой. Есть криптоПро и ключи у пользователя. У плагина криптоПро есть потоковый интерфейс для шифрования и дешифрования.

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

  Развернуть 1 комментарий

@norguhtar, Побил на чанки, получилось пропроцессить файл размеров в 10гб
Тестирвоал на хроме 84, макбук про 16
репа с эксперементами: https://github.com/instingt/chunk-process-example

Отказ от ответственнсти: не продакшен реди, использовать на свой страх и риск :D

  Развернуть 1 комментарий

@Vita, нууу так я тоже умею. А закладка не лопнет? Меня вот это смущает.

  Развернуть 1 комментарий

@norguhtar, у меня не лопнуло. Сгенерировал через dd файл размером 10гигабайт из нулей, на выходе получил файл, где каждый байт инкрементирован. Время выполнения около 2-3 минут

  Развернуть 1 комментарий

@Vita, ну окей поиграюсь. Кстати да ну раз такая пьянка
как-то вот такое улучшить можно ?

    let sBase64Data = btoa(new Uint8Array(chunk).reduce((data, byte) => (
        data.push(String.fromCharCode(byte)), data), []).join('')
    );
	
	    let sdBase64Data = Uint8Array.from(atob(encryptData), c => c.charCodeAt(0));
		

А то есть ощущение что генерация идет не быстро.

  Развернуть 1 комментарий
  Развернуть 1 комментарий

@norguhtar, да особо никак. Единственное что могу посоветовать - это выделить сразу массив нужной длины. Тогда интрепритатору не придется каждый раз пересоздоваться массив и переносить уже прочитанные байтики из старого в новый.

  Развернуть 1 комментарий

@Vita, эх. Поменяю тогда и так и так.

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб