Javascript 如何使用 window.fetch 下载文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32545632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I download a file using window.fetch?
提问by syg
If I want to download a file, what should I do in the then
block below?
如果我想下载一个文件,我应该在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(...);
}
Note the codes are in client-side.
注意代码在客户端。
采纳答案by syg
I temporarily solve this problem by using download.jsand blob
.
我通过使用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);
});
}
It's working for small files, but maybe not working for large files. I think I should dig Streammore.
它适用于小文件,但可能不适用于大文件。我想我应该更多地挖掘Stream。
回答by Mariusz Pawelski
EDIT: syg answer is better. Just use downloadjslibrary.
编辑:syg 答案更好。只需使用downloadjs库。
The answer I provided works well on Chrome, but on Firefox and IE you need some different variant of this code. It's better to use library for that.
我提供的答案在 Chrome 上运行良好,但在 Firefox 和 IE 上,您需要此代码的一些不同变体。最好为此使用库。
I had similar problem (need to pass authorization header to download a file so thissolution didn't helped).
我有类似的问题(需要通过授权标头来下载文件,所以这个解决方案没有帮助)。
But based on thisanswer you can use createObjectURL
to make browser save a file downloaded by Fetch API.
但是基于此答案,您可以使用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
});
});
回答by Zibri
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");
or:
或者:
function download(url, filename) {
fetch(url).then(function(t) {
return t.blob().then((b)=>{
var a = document.createElement("a");
a.href = URL.createObjectURL(b);
a.setAttribute("download", filename);
a.click();
}
);
});
}
download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");
回答by Lucas Matos
This is more shorter and efficient, no libraries only fetch API
这更短更高效,没有库只获取 API
const url ='http://sample.example.file.doc'
const authHeader ="Bearer 6Q************"
const options = {
headers: {
Authorization: authHeader
}
};
fetch(url, options)
.then( res => res.blob() )
.then( blob => {
var file = window.URL.createObjectURL(blob);
window.location.assign(file);
});
回答by Daniel
Using dowloadjs. This will parse the filename from the header.
使用下载js。这将从标题中解析文件名。
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");
});
};
回答by Michael Hobbs
Here is an example using node-fetch for anyone that finds this.
这是一个使用 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)
}
回答by Maddocks
I tried window.fetch but that ended up being complicated with my REACT app
我试过 window.fetch 但结果我的 REACT 应用程序变得很复杂
now i just change window.location.href and add query params like the jsonwebtoken
and other stuff
.
现在我只是更改 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)
the end results actually end up being pretty nice, the window makes request and downloads the file and doesn't event switch move the page away, its as if the window.location.href
call was like a lowkey fetch()
call.
最终结果实际上非常好,窗口发出请求并下载文件,并且没有事件开关将页面移开,就好像window.location.href
呼叫就像一个低调的fetch()
呼叫。
回答by Yuci
As per some of the other answers, you can definitely use window.fetch and download.jsto download a file. However, using window.fetch with blob has the restriction on memory imposed by the browser, and the download.js also has its compatibility restrictions.
根据其他一些答案,您绝对可以使用 window.fetch 和download.js下载文件。但是,使用window.fetch 和blob 有浏览器对内存的限制,而download.js 也有其兼容性限制。
If you need to download a big-sized file, you don't want to put it in the memory of the client side to stress the browser, right? Instead, you probably prefer to download it via a stream. In such a case, using an HTML link to download a file is one of the best/simplest ways, especially for downloading big-sized files via a stream.
如果你需要下载一个大文件,你不想把它放在客户端的内存中给浏览器带来压力,对吧?相反,您可能更喜欢通过流下载它。在这种情况下,使用 HTML 链接下载文件是最好/最简单的方法之一,尤其是通过流下载大文件。
Step One:create and style a link element
第一步:创建链接元素并为其设置样式
You can make the link invisible but still actionable.
您可以使链接不可见,但仍可操作。
HTML:
HTML:
<a href="#" class="download-link" download>Download</a>
CSS:
CSS:
.download-link {
position: absolute;
top: -9999px;
left: -9999px;
opacity: 0;
}
Step Two:Set the href
of the link, and trigger the click
event
第二步:设置href
链接的,并触发click
事件
JavaScript
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()
Note: you can dynamically generate the link element if necessary.
注意:如有必要,您可以动态生成链接元素。