[Занимательные задачки, JavaScript, Google Chrome, Браузеры] Как обойти ограничение браузера и прикрепить сразу два файла и более: мультидобавление файлов
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Привет, Хабр!
Давайте решим нетривиальную задачу. Представьте, что вам нужно скачать данные через интерфейс элементарным способом, например, кликнуть по кнопке «Скачать файлы».
Возьмём по умолчанию Chrome v.88. Задача звучит так:
- Сгенерировать файлы на стороне клиента.
- Скачать все сгенерированные файлы одним кликом.
Это может быть всё что угодно: кучка бинарников, большие архивы с бэкапами, галерея картинок и прочее. Мы же будем говорить именно о механизме скачивания как таковом, поэтому в качестве примера возьмём скачивание текста и картинок.
Само собой, можно решить такую задачу, просто сжав все нужные файлы в один ZIP-архив, а потом уже скачать его. Выходит, пользователь скачает единый файл, который потом самостоятельно разархивирует. Например, можно использовать библиотеку jszip, которая позволяет скачивать набор файлов, сжав их.
Вот небольшой пример скачивания с предварительным сжатием из документации:
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true}); zip.generateAsync({type:"blob"}).then(function(content) {
// see FileSaver.js
saveAs(content, "example.zip"); });
«А где тут нетривиальность?» — спросите вы. И будете правы. А если речь идёт об одновременном скачивании с сайта двух, трёх или десяти файлов? Например: есть лист в селекте, в котором можно выбрать определённое количество файлов для скачивания. Введём дополнительное условие: у пользователя нет установленного архиватора, поэтому вариант со сжатием в архив отбрасываем. Как решить такую задачу?
Сначала подготовим браузер. Chrome по умолчанию запрещает скачивать мультифайлы. Это сделано в целях безопасности. Поэтому эту функцию надо сначала разблокировать в настройках браузера:
- Заходим в настройки сайтов: chrome://settings/content.
- Переходим в доступ дополнительных прав (Additional permissions).
- Выбираем Automatic downloads.
- Добавляем необходимый сайт в категорию Allow.
Отлично, теперь ваш браузер стал менее безопасным позволяет скачивать на конкретном сайте сразу несколько файлов.
Подход #1 — FileReader
Первый подход рассмотрим на примере генерации файлов с помощью FileReader и API для чтения base64. Отмечу сразу, что у FileReader довольно обширное API, поэтому выбирайте то, что больше нравится: text, arrayBuffer или binaryString.
(function () {
const button = document.getElementById("download_with_reader");
const content = ["content-1", "content-2", "content-3"];
const createLink = () => {
let link = document.createElement('a');
link.download = 'hello.txt';
return link;
}
const generateBlob = () => {
for (const [index, value] of content.entries()) {
const blob = new Blob([value], { type: "text/plain" });
download(blob, index);
}
}
const download = (blob, index) => {
const link = createLink();
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function () {
link.href = reader.result;
link.download = `content-${index+1}.txt`;
link.click();
}
}
button.addEventListener("click", generateBlob);
}) ();
[код на Gitlab]
Подход #2 — createObjectURL
А ещё можно использовать createObjectURL — он позволяет хранить File-объекты или Blob-объекты.
(function () {
const button = document.getElementById("download_with_url_object");
const content = ["content-1", "content-2", "content-3"];
const createLink = () => {
let link = document.createElement('a');
link.download = 'hello.txt';
return link;
}
const generateBlob = () => {
for (const [index, value] of content.entries()) {
const blob = new Blob([value], { type: "text/plain" });
download(blob, index);
}
}
const download = (blob, index) => {
const link = createLink();
link.href = URL.createObjectURL(blob);
link.download = `content-${index+1}.txt`;
link.click();
URL.revokeObjectURL(link.href);
}
button.addEventListener("click", generateBlob);
}) ();
[код на Gitlab]
Подход #3 — Скачивание по URL
Два варианта выше генерируют файлы на стороне клиента. Конечно, так будет не всегда, время от времени мы получаем файлы со стороны бэкенда по прямым ссылкам. Это можно реализовать с помощью скачивания по URL. Chrome требует, чтобы была задержка, поэтому особенностью этого метода и станет реализация искусственной задержки.
(function () {
(function () {
const button = document.getElementById("download_with_request");
const urls = ["images/image-1.jpg", "images/image-2.jpg", "images/image-3.jpg"];
const delay = () => new Promise(resolve => setTimeout(resolve, 1000));
const downloadWithRequest = async () => {
for await (const [index, url] of urls.entries()) {
await delay();
const link = document.createElement("a");
link.href = url;
link.download = `image-${index+1}`;
link.click();
}
}
button.addEventListener("click", downloadWithRequest);
}) ();
[код на Gitlab]
Итого
Вот три довольно простых способа, с помощью которых можно одновременно скачать несколько файлов с сайта и сделать это быстро. Главное — включите нужные разрешения для конкретного сайта, а затем выбирайте способ по душе.
===========
Источник:
habr.com
===========
Похожие новости:
- [JavaScript, Программирование, HTML, TensorFlow] Обнаружение эмоций на лице в браузере с помощью глубокого обучения и TensorFlow.js. Часть 2 (перевод)
- [JavaScript, API] ExtendScript + Expression
- [JavaScript, Программирование] Зависимости JavaScript: Все, что вы когда-либо хотели знать, но боялись спросить (перевод)
- [JavaScript, ReactJS] Какая настоящая цена useMemo?
- [JavaScript, ReactJS] Biscuit-store — еще один взгляд на state-management в JavaScript приложениях
- [JavaScript, Программирование, HTML, TensorFlow] Отслеживание лиц в реальном времени в браузере с использованием TensorFlow.js. Часть 1 (перевод)
- [JavaScript, Программирование] Почему вы можете обойтись без Babel (перевод)
- [Исследования и прогнозы в IT, Учебный процесс в IT, Карьера в IT-индустрии] Из каких областей чаще всего приходят учиться, чтобы сменить сферу деятельности. Исследование от Яндекс.Практикума
- [Информационная безопасность, Разработка веб-сайтов, Google Chrome, Браузеры] Разработчики Chrome внедряют принудительное открытие сайтов через HTTPS
- [Децентрализованные сети, Сетевые технологии, I2P, Браузеры, Законодательство в IT] Цензура в интернете. Когда базовых мер недостаточно — I2P
Теги для поиска: #_zanimatelnye_zadachki (Занимательные задачки), #_javascript, #_google_chrome, #_brauzery (Браузеры), #_jandeks.praktikum (яндекс.практикум), #_javascript, #_brauzery (браузеры), #_skachivanie_fajlov (скачивание файлов), #_blog_kompanii_jandeks.praktikum (
Блог компании Яндекс.Практикум
), #_zanimatelnye_zadachki (
Занимательные задачки
), #_javascript, #_google_chrome, #_brauzery (
Браузеры
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:58
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Привет, Хабр! Давайте решим нетривиальную задачу. Представьте, что вам нужно скачать данные через интерфейс элементарным способом, например, кликнуть по кнопке «Скачать файлы». Возьмём по умолчанию Chrome v.88. Задача звучит так:
Это может быть всё что угодно: кучка бинарников, большие архивы с бэкапами, галерея картинок и прочее. Мы же будем говорить именно о механизме скачивания как таковом, поэтому в качестве примера возьмём скачивание текста и картинок. Само собой, можно решить такую задачу, просто сжав все нужные файлы в один ZIP-архив, а потом уже скачать его. Выходит, пользователь скачает единый файл, который потом самостоятельно разархивирует. Например, можно использовать библиотеку jszip, которая позволяет скачивать набор файлов, сжав их. Вот небольшой пример скачивания с предварительным сжатием из документации: var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n"); var img = zip.folder("images"); img.file("smile.gif", imgData, {base64: true}); zip.generateAsync({type:"blob"}).then(function(content) { // see FileSaver.js saveAs(content, "example.zip"); }); «А где тут нетривиальность?» — спросите вы. И будете правы. А если речь идёт об одновременном скачивании с сайта двух, трёх или десяти файлов? Например: есть лист в селекте, в котором можно выбрать определённое количество файлов для скачивания. Введём дополнительное условие: у пользователя нет установленного архиватора, поэтому вариант со сжатием в архив отбрасываем. Как решить такую задачу? Сначала подготовим браузер. Chrome по умолчанию запрещает скачивать мультифайлы. Это сделано в целях безопасности. Поэтому эту функцию надо сначала разблокировать в настройках браузера:
Отлично, теперь ваш браузер стал менее безопасным позволяет скачивать на конкретном сайте сразу несколько файлов. Подход #1 — FileReader Первый подход рассмотрим на примере генерации файлов с помощью FileReader и API для чтения base64. Отмечу сразу, что у FileReader довольно обширное API, поэтому выбирайте то, что больше нравится: text, arrayBuffer или binaryString. (function () {
const button = document.getElementById("download_with_reader"); const content = ["content-1", "content-2", "content-3"]; const createLink = () => { let link = document.createElement('a'); link.download = 'hello.txt'; return link; } const generateBlob = () => { for (const [index, value] of content.entries()) { const blob = new Blob([value], { type: "text/plain" }); download(blob, index); } } const download = (blob, index) => { const link = createLink(); let reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function () { link.href = reader.result; link.download = `content-${index+1}.txt`; link.click(); } } button.addEventListener("click", generateBlob); }) (); [код на Gitlab] Подход #2 — createObjectURL А ещё можно использовать createObjectURL — он позволяет хранить File-объекты или Blob-объекты. (function () {
const button = document.getElementById("download_with_url_object"); const content = ["content-1", "content-2", "content-3"]; const createLink = () => { let link = document.createElement('a'); link.download = 'hello.txt'; return link; } const generateBlob = () => { for (const [index, value] of content.entries()) { const blob = new Blob([value], { type: "text/plain" }); download(blob, index); } } const download = (blob, index) => { const link = createLink(); link.href = URL.createObjectURL(blob); link.download = `content-${index+1}.txt`; link.click(); URL.revokeObjectURL(link.href); } button.addEventListener("click", generateBlob); }) (); [код на Gitlab] Подход #3 — Скачивание по URL Два варианта выше генерируют файлы на стороне клиента. Конечно, так будет не всегда, время от времени мы получаем файлы со стороны бэкенда по прямым ссылкам. Это можно реализовать с помощью скачивания по URL. Chrome требует, чтобы была задержка, поэтому особенностью этого метода и станет реализация искусственной задержки. (function () {
(function () { const button = document.getElementById("download_with_request"); const urls = ["images/image-1.jpg", "images/image-2.jpg", "images/image-3.jpg"]; const delay = () => new Promise(resolve => setTimeout(resolve, 1000)); const downloadWithRequest = async () => { for await (const [index, url] of urls.entries()) { await delay(); const link = document.createElement("a"); link.href = url; link.download = `image-${index+1}`; link.click(); } } button.addEventListener("click", downloadWithRequest); }) (); [код на Gitlab] Итого Вот три довольно простых способа, с помощью которых можно одновременно скачать несколько файлов с сайта и сделать это быстро. Главное — включите нужные разрешения для конкретного сайта, а затем выбирайте способ по душе. =========== Источник: habr.com =========== Похожие новости:
Блог компании Яндекс.Практикум ), #_zanimatelnye_zadachki ( Занимательные задачки ), #_javascript, #_google_chrome, #_brauzery ( Браузеры ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 08:58
Часовой пояс: UTC + 5