Как загрузить файл с помощью window.fetch?
Если я хочу загрузить файл, что мне делать в блоке then
ниже?
function downloadFile(token, fileId) {
let url = `https://www.googleapis.com/drive/v2/files/${fileId}?alt=media`;
return fetch(url, {
method: 'GET',
headers: {
'Authorization': token
}
}).then(...);
}
Обратите внимание, что коды находятся на стороне клиента.
Ответы
Ответ 1
Я временно решу эту проблему, используя download.js и blob
.
let download = require('./download.min');
...
function downloadFile(token, fileId) {
let url = `https://www.googleapis.com/drive/v2/files/${fileId}?alt=media`;
return fetch(url, {
method: 'GET',
headers: {
'Authorization': token
}
}).then(function(resp) {
return resp.blob();
}).then(function(blob) {
download(blob);
});
}
Он работает для небольших файлов, но, возможно, не работает для больших файлов. Я думаю, что я должен больше Stream.
Ответ 2
РЕДАКТИРОВАТЬ: syg ответ лучше. Просто используйте библиотеку downloadjs.
Ответ, который я предоставил, хорошо работает в Chrome, но в Firefox и IE вам нужен другой вариант этого кода. Для этого лучше использовать библиотеку.
У меня была похожая проблема (нужно передать заголовок авторизации для загрузки файла, чтобы это решение не помогло).
Но на основании этого ответа вы можете использовать createObjectURL
чтобы браузер сохранил файл, загруженный с помощью Fetch API.
getAuthToken()
.then(token => {
fetch("http://example.com/ExportExcel", {
method: 'GET',
headers: new Headers({
"Authorization": "Bearer " + token
})
})
.then(response => response.blob())
.then(blob => {
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = "filename.xlsx";
document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox
a.click();
a.remove(); //afterwards we remove the element again
});
});
Ответ 3
Вот пример использования node-fetch для любого, кто находит это.
reportRunner({url, params = {}}) {
let urlWithParams = '${url}?'
Object.keys(params).forEach((key) => urlWithParams += '&${key}=${params[key]}')
return fetch(urlWithParams)
.then(async res => ({
filename: res.headers.get('content-disposition').split('filename=')[1],
blob: await res.blob()
}))
.catch(this.handleError)
}
Ответ 4
Использование dowloadjs. Это будет анализировать имя файла из заголовка.
fetch("yourURL", {
method: "POST",
body: JSON.stringify(search),
headers: {
"Content-Type": "application/json; charset=utf-8"
}
})
.then(response => {
if (response.status === 200) {
filename = response.headers.get("content-disposition");
filename = filename.match(/(?<=")(?:\\.|[^"\\])*(?=")/)[0];
return response.blob();
} else {
return;
}
})
.then(body => {
download(body, filename, "application/octet-stream");
});
};
Ответ 5
function download(dataurl, filename) {
var a = document.createElement("a");
a.href = dataurl;
a.setAttribute("download", filename);
a.click();
return false;
}
download("data:text/html,HelloWorld!", "helloWorld.txt");
Ответ 6
Я попробовал window.fetch, но это оказалось сложно с моим приложением REACT
Теперь я просто изменил window.location.href и добавил параметры запроса, такие как jsonwebtoken
и other stuff
.
///==== client side code =====
var url = new URL('http://${process.env.REACT_APP_URL}/api/mix-sheets/list');
url.searchParams.append("interval",data.interval);
url.searchParams.append("jwt",token)
window.location.href=url;
// ===== server side code =====
// on the server i set the content disposition to a file
var list = encodeToCsv(dataToEncode);
res.set({"Content-Disposition":'attachment; filename=\"FileName.csv\"'});
res.status(200).send(list)
конечные результаты на самом деле оказываются довольно хорошими, окно делает запрос и загружает файл, а переключатель событий не перемещает страницу, как если бы вызов window.location.href
был похож на вызов lowkey fetch()
.
Ответ 7
Что касается некоторых других ответов, вы можете использовать window.fetch и download.js, чтобы загрузить файл. Тем не менее, использование window.fetch с blob имеет ограничение на память, наложенное браузером, а download.js также имеет свои ограничения совместимости.
Если вам нужно скачать файл большого размера, вы не хотите помещать его в память клиентской части, чтобы подчеркнуть браузер, верно? Вместо этого вы, вероятно, предпочитаете скачать его через поток. В таком случае использование ссылки HTML для загрузки файла является одним из лучших/самых простых способов, особенно для загрузки файлов большого размера через поток.
Шаг первый: создать и стилизовать элемент ссылки
Вы можете сделать ссылку невидимой, но все же действующей.
HTML:
<a href="#" class="download-link" download>Download</a>
CSS:
.download-link {
position: absolute;
top: -9999px;
left: -9999px;
opacity: 0;
}
Шаг второй: Установите href
ссылки и запустите событие click
JavaScript
let url = 'https://www.googleapis.com/drive/v2/files/${fileId}?alt=media';
const downloadLink = document.querySelector('.download-link')
downloadLink.href = url + '&ts=' + new Date().getTime() // Prevent cache
downloadLink.click()
Примечание: при необходимости вы можете динамически генерировать элемент ссылки.