[英]How to trigger a browser download from a browser FETCH?
我正在开发一个项目,前端使用Vue.js和Typescript ,后端使用Java Spring 。
我的 java 控制器从数据库中检索给定的报告,然后将其复制到 HTML 响应中。 我希望浏览器下载 CSV,因此我在响应中添加了Content-disposition标头。
@GetMapping('/download')
public void downloadCSV(HttpServletRequest response){
Report r = reportService.findById(85);
response.addHeader("Content-Disposition", "attachment; filename=myCSV.csv");
response.setContentType("text/csv");
try {
InputStream stream = new ByteArrayInputStream(r.getDocument());
IOUtils.copy(stream, response.getOutputStream());
response.flushBuffer();
} catch(Exception e) {...}
}
我有 2 个按钮:一个简单的超链接标签,带有链接到download() 的href 和一个 b 按钮(来自 bootstrap-vue),一旦点击就会触发download2() 。
<a :href="download" role="button"> Download CSV </a>
<b-button @click="event => download2()">
Download CSV v2
</b-button>
get download(): string {
return 'http://localhost:8080/download';
}
async download2() {
const rHeaders = new Headers();
rHeaders.append('Accept', 'text/csv');
const configInit = RequestInit = {
method: 'GET',
headers: rHeaders
};
try {
const res = await fetch('http://localhost:8080/download', configInit);
return res.text();
} catch (e) {...}
}
现在,如果我单击第一个按钮“下载 csv”,则浏览器会正确下载 csv。 javascript 控制台打印以下内容:
Resource interpreted as Document but transferred with MIME type text/csv
并且响应体中没有任何内容。
相反,如果我单击第二个按钮“下载 csv v2”,下载不会开始,但我的响应正文中有 csv。
在这里,两者之间请求标头的差异。
*Header* *Download csv* *Download csv v2*
Sec-Fetch-Dest document empty
Sec-Fetch-Mode navigate cors
Sec-Fetch-User ?1 -
Upgrade-Insecure-Requests 1 -
其他标题相同。 即使我在 javascript 方法中设置它们,也无法更改这些标题; 它们保持不变。 有什么问题? 谢谢你。
我通过“模仿” <a>
元素的行为找到了一个解决方案:
这样,它可以正常工作:
async download2() {
const configInit: RequestInit = {
method: 'GET'
};
try {
await fetch('http://localhost:8080/download', configInit)
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'report.csv';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
} catch (e) {...}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.