В нашем приложении мы разрешаем пользователям скачивать файлы pdf / excel. Эти файлы являются личными для пользователя и не должны быть доступны неавторизованным пользователям. Мы вроде как поняли, как это сделать с помощью Auth, но все же хотели изучить различные варианты загрузки файлов с помощью Javascript.

Ниже приведены некоторые способы загрузки файлов Javascript:

Создайте ссылку с соответствующим href:
Если у вас уже есть ссылка на файл, который необходимо загрузить, вы можете использовать ее как href в теге привязки. Когда пользователь нажимает на ссылку, браузер пытается открыть этот файл как статический ресурс, если браузер может предварительно просмотреть его, он откроет предварительный просмотр и позволит пользователю загрузить, если он захочет.
( См. Здесь, чтобы понять, как браузер принимает решение о предварительном просмотре или загрузке файла).

<a href="fileurl"> Download </a>

Создайте ссылку с соответствующим атрибутом href И загрузки:
Вы можете заставить браузер не открывать предварительный просмотр, а напрямую открывать диалоговое окно «Сохранить файл», установив атрибут download для ссылки. Значение атрибута download - это предлагаемое имя файла для сохранения. Атрибут download переопределит любое значение Content-Disposition: inline и не будет отображать предварительный просмотр.

<a href="fileurl" download="suggestedfilename"> Download </a>

window.open с _blank:
Если вы не можете или не хотите использовать тег привязки (так как он будет отображать URL-адрес при наведении курсора, чего вы, возможно, захотите избежать), затем вы можете использовать кнопку и при нажатии открыть новое окно с URL-адресом файла. После этого браузер покажет либо предварительный просмотр, либо диалоговое окно Сохранить файл на основе заголовков ответов. Это имеет побочный эффект, заключающийся в том, что открывается новое окно, даже если вы хотели только загрузить файл, но недавние браузеры автоматически закрывают окно после загрузки файла.
Вы можете столкнуться с некоторыми проблемами с блокировкой всплывающих окон при использовании window.open, в зависимости от того, используете ли вы его в асинхронном обратном вызове.

window.open(fileurl, "_blank");

window.open with _self:
Если вы вообще не хотите открывать новое окно и разрешить загрузку из того же окна / вкладки, вы можете использовать window.open (fileurl , "_себя"). Это нормально работает, если предполагается, что файл будет загружен напрямую. В случае предварительного просмотра он открывается в том же окне, что и ваше приложение, что в большинстве случаев нежелательно.

window.open(fileurl, "_self");

Создайте скрытую ссылку и активируйте щелчок по ней:
При нажатии кнопки вместо использования window.open вы также можете создать скрытую ссылку в своем коде, установить необходимые href, и вызвать щелчок из javascript.

const link = document.createElement("a");
document.body.appendChild(link);
link.href = url;
link.setAttribute("type", "hidden");
link.setAttribute("download", true);
link.click();

Создайте скрытый iframe:
Здесь не обсуждается, но отчасти похоже на window.open.

Хорошая подборка трюков, но как все это работает за Auth?

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

Как обсуждалось здесь, одним из вариантов является:

  • загрузите файл из приложения, отправив заголовки аутентификации,
  • создать URL-адрес большого двоичного объекта
  • установить URL-адрес большого двоичного объекта как ссылку href

теперь пользователь может щелкнуть ссылку, чтобы открыть / скачать файл. Этот подход аналогичен тому, что обсуждается в приведенном выше сообщении для изображений, но это фактически означает, что приложение должно управлять всей загрузкой, что, если файл очень большой и не может быть преобразован в большой двоичный объект? Было бы лучше позволить браузеру решать все эти проблемы.

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

Что касается UX, одним из способов справиться с этим было бы отображение кнопки с надписью «Создать ссылку для загрузки», при нажатии на которую мы можем получить токен и показать ссылку в пользовательском интерфейсе, по которой пользователь может затем щелкнуть, чтобы загрузить файл. . Но в нашем сценарии мы не хотели этого косвенного обращения, мы хотели иметь кнопку «Загрузить» и запускать загрузку, как только токен станет доступен, не прося пользователя щелкнуть другую ссылку, поэтому в итоге мы использовали окно. open, чтобы запустить загрузку файла, как только у нас будет токен.

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

Затем мы можем использовать любой из этих методов для запуска фактической загрузки: window.open, скрытая ссылка или iframe.

Это рабочий процесс:

  • Приложение показывает пользователю кнопку «Загрузить».
  • Пользователь нажимает на кнопку.
  • Приложение запрашивает у серверной части недолговечный токен загрузки. Эта конечная точка получения токена вызывается из приложения и использует информацию об авторизации пользователя в заголовке. Бэкэнд проверяет, запрашивает ли авторизованный пользователь токен загрузки, и возвращает недолговечный (в нашем случае 2 минуты) токен.
  • Затем приложение создает URL-адрес загрузки, добавляя токен к имени файла.
  • Приложение использует window.open (fileurl-with-token) для запуска фактической загрузки.

Использованная литература: