Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Загрузка файла пользователю на комп при нажатии на кнопки на UI (https://javascript.ru/forum/dom-window/85341-zagruzka-fajjla-polzovatelyu-na-komp-pri-nazhatii-na-knopki-na-ui.html)

Steven100500 04.07.2023 16:57

Загрузка файла пользователю на комп при нажатии на кнопки на UI
 
Добрый день, подскажите, пожалуйста, можно ли файл, хранимый в виде массива byte[], загружать пользователю на комп при нажатии кнопки на стороне клиента? (т.е. по аналогии с нажатием на тег с атрибутами href - с указанием ссылки на файл - и download), просто файл, лежащий на сервере напрямую мешают выгрузить настройки безопасности, видимо. Если даю ссыль - файл не загружается с ошибкой 400 - Not allowed to load local resource: далее URI идет.)

voraa 04.07.2023 17:27

Если браузер может загрузить этот файл с сервера, то он сможет его выгрузить его на компьютер пользователя. Естественно с согласия пользователя.
Примерно такая последовательность действий
// Загрузить файл с сервера в виде Blob
const res = await fetch ('url на сервере');
const blob = await res.blob();

//Создать ObjectURL на этот Blob
const hrefurl =  window.URL.createObjectURL(blob);

//Создать с помощью js элемент <а> с href с  этим ObjectURL и атрибутом downloal
const a = document.createElement ('a');
a.download = '';
a.href = hrefurl;
//Проимитировать клик на элементе a
a.click();


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

Steven100500 04.07.2023 17:39

Спасибо большое, буду пробовать!

Steven100500 04.07.2023 17:41

Я понял, благодарю. Источник один и тот же. Файл я могу копирнуть в виде массива байт на серваке и передать в кач-ве респонса. Рисунки я уже передаю в формате base64, по крайней мере, img их в виде сорсов кушает преспокойно. Но теперь интересны другие форматы и уже в виде выгрузки на устройство юзверя.

voraa 04.07.2023 17:49

Тут надо знать (или экспериментировать).
Может быть с fetch надо передавать заголовки, указывая MIME файла, который запрашивается.
Может быть у <a> надо установить атрибут type с необходимым MIME.

Steven100500 04.07.2023 17:53

Варюсь в этой теме всего полтора месяца. Буду экспериментировать =)

Steven100500 05.07.2023 16:00

В общем, сделал передачу файла в виде текста base64 с последующей выгрузкой на комп пользователя следующим образом:
1) Отдельно прописал функцию
urlToFile: async function(url, filename, mimeType) {
const res = await fetch(url);
const buf = await res.arrayBuffer();
return new File([buf], filename, { type: mimeType });
}
2) при нажатии на кнопку вызывается функция:
$(`id_кнопы`).click(function (e) {
e.preventDefault();
if ("файл_преобразованный_в_те ст_в_формате_base64") {
(async () => {
const file = await self.urlToFile(
`data:text/plain;base64,${fileInfo.AddPhotoData.bFile}`,
`hello.${переменная_с_расширен ем_файла}`,
"text/plain"
);
let fileLink = window.URL.createObjectURL(file);
const a = document.createElement('a');
a.download = fileInfo.AddPhotoData.PhotoName;
a.href = fileLink;
a.click();
})();
}
}
PS self - модуль, в котором лежит функция urlToFile. Даже не модуль, а не знаю, как назвать - может , класс, может пространство имен, на которую указывает переменная self. Ну, и никто не мешает сделать импорт из модуля =)
Огромное спасибо за помощь!!!! Подсказали, куда копать.

рони 05.07.2023 17:52

Steven100500,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.


Часовой пояс GMT +3, время: 17:53.