- 1、a标签url下载
- 1.1、a标签download属性下载
- 2、把地址传入浏览器地址中触发下载
- 2.1、通过js构建a标签进行下载
- 3、form表单提交下载
- 其他下载方式
- 下载后缀为
.lnk
遇到的怪事 - Q&A
平时我们在前端项目中都是怎么下载资源的?比如一个word文档等,这里简单总结了4种方式。
1、a标签url下载
exportUrl 是下载地址,点击之后直接在当前界面下载文件
<a :href="exportUrl" class="g-button simple">导出</a>
1.1、a标签download属性下载
a标签的
download
是HTML5标准新增的属性,作用是指示浏览器下载URL而不是导航到URL,因此将提示用户将其保存为本地文件。
代码示例:
<a href="http://ww2.sinaimg.cn/large/4b4d632fgw1f1hhza4495j20ku0rsjxs.jpg" download>下载</a>
注意:此属性仅适用于同源 URL,跨域的资源无效。
那么如何解决跨域文件?
尽管 HTTP URL 需要位于同一源中,但是可以使用 blob: URL
和 data: URL
,以方便用户下载使用 JavaScript 生成的内容以解决跨域问题。
跨域资源下载:
// 下载一个文本文件
const downloadText = (text, filename = '') {
const a = document.createElement('a')
a.download = filename
// 文本txt类型
const blob = new Blob([text], {type: 'text/plain'})
// text指需要下载的文本或字符串内容
a.href = window.URL.createObjectURL(blob)
// 会生成一个类似blob:http://localhost:8080/d3958f5c-0777-0845-9dcf-2cb28783acaf 这样的URL字符串
document.body.appendChild(a)
a.click()
a.remove()
}
2、把地址传入浏览器地址中触发下载
window.open(exportUrl, '_self'); // 本窗口打开下载,地址栏的地址并不会改变
window.open(exportUrl, '_blank'); // 新开窗口下载
2.1、通过js构建a标签进行下载
const link = document.createElement("a");
link.href = `${BASEURL}sftp/${row.id}/download/exec`;
link.setAttribute("download", 'test.png'); //设置下载属性 以及文件名
document.body.appendChild(link); //a标签插至页面中
link.click(); //强制触发a标签事件
document.body.removeChild(link);
3、form表单提交下载
form表单的提交本质上是发送了一次HTTP请求。
<form>
元素定义了如何发送数据。它的所有属性都是为了让您配置当用户点击提交按钮时发送的请求。两个最重要的属性是action
和method
。
action属性
这个属性定义了发送数据要去的位置。它的值必须是一个有效的URL。如果没有提供此属性,则数据将被发送到包含这个表单的页面的URL。
method属性
该属性定义了如何发送数据。HTTP协议提供了几种执行请求的方法;HTML表单数据可以通过许多不同的方法进行数据传输,其中最常见的是GET
方法和POST
方法。
想要form提交数据,需要把form的action
设置为接口地址,method一般设置为post
,post到后台的数据为input的属性 name = key
,value = value
的形式。
- 如果有多个key、value的值要传递,那么就设置多个input来分别储存单个的key、value;
- 如果请求的接口可以不需要参数,那么input还是必须要一个,如果不要得话会引起接口报错。
<form action="http://xxx.com" method="post">
<div>
<label for="say">What greeting do you want to say?</label>
<input name="say" id="say" value="Hi">
</div>
<div>
<label for="to">Who do you want to say it to?</label>
<input name="to" id="to" value="Mom">
</div>
<div>
<button>Send my greetings</button>
</div>
</form>
发送的表单数据为:
POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
say=Hi&to=Mom
下面是封装的一个jQuery插件,使用form的形式发起http请求:
$.download = function (url, params, method) {
if (url && params) {
var inputs = '', input, form = $('<form />').attr("action", url).attr("method", (method || "post"));
$.each(params, function (k, v) {
input = $("<input type='hidden' />");
input.attr("name", k).attr("value", v);
form.append(input);
});
form.appendTo('body').submit().remove();
}
};
使用方法:
var url = "/app/lottery/awards/export", params = { FILETYPE: "excel07", FRMID: that.FRMID };
$.download(url, params, "post");
参考链接:https://developer.mozilla.org/zh-CN/docs/Learn/Forms/Sending_and_retrieving_form_data
其他下载方式
/**
* 下载文件。数据源是Blob对象
*/
export const downloadBlobFile = (binaryString, fileName) => {
const blob = new Blob([binaryString], { type: "application/octet-stream" });
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
//延时释放
setTimeout(function () {
window.URL.revokeObjectURL(link.href);
}, 100);
};
/**
* 下载文件。数据源是base64
*/
export const downloadBase64File = (data, fileName, headerType) => {
const link = document.createElement("a");
const header = headerMap[headerType || ""] || "";
link.href = header + ";base64," + data;
link.download = fileName;
link.click();
};
/**
* 通过文件地址下载文件
*/
export const downloadURLFile = (url, fileName) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url.replace(/\\/g, "/"), true);
xhr.responseType = "blob";
xhr.onload = () => {
if (xhr.status === 200) {
downloadBlobFile(xhr.response, fileName);
}
};
xhr.send();
};
下载后缀为.lnk
遇到的怪事
有用户反馈,下载的.lnk文件,后缀名变成了.download。
经查,只有chrome系列浏览器才有这个问题。
抓包看下请求,发现服务端在response的header里给出了正确的文件名,如:Content-Disposition: attachment; filename="xxx.lnk"
那么,这个重命名肯定是浏览器的默认行为。实际上,lnk类型的文件是一个软链,运行后会执行什么完全取决于不同的系统环境,没办法预期,Chrome认为这比较危险,就在底层强制对其重命名了。所以,这不是web应用所能决定的。
参考地址:https://imququ.com/post/download-link-file-issue-with-chrome.html
Q&A
你在前端项目中都是怎么下载文件的?欢迎再评论区和我交流吧!
(完)