原生js实现文件下载的几种情况

Posted 问海螺吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生js实现文件下载的几种情况相关的知识,希望对你有一定的参考价值。

内容来源:

https://www.cnblogs.com/ajaxkong/p/11686041.html

1:一般通过a标签的方式下载,利用H5的Download属性

代码示例如下:

场景:适用于现代浏览器,url是下载地址,而不是文件流,常用于GET请求

复制代码
 1 function downLoad(downUrl, fileName) {
 2   let a = document.createElement("a");// 创建a标签
 3   if (\'download\' in a) {
 4     a.download = fileName;// 设置下载文件的文件名
 5   }
 6   (document.body || document.documentElement).appendChild(a);
 7   a.href = downUrl;// downUrl为后台返回的下载地址
 8   a.target = \'_parent\';
 9   a.click();// 设置点击事件
10   a.remove(); // 移除a标签
11 }
12 
13 downLoad(URL, \'test.xlxs\') //URL下载地址
复制代码

 

如果后台给的是文件流,则利于Blob对象包装一下文件流,常用于POST请求

代码示例如下:

复制代码
 1 function downLoad(content, fileName) {
 2   let a = document.createElement("a"),// 创建a标签
 3       blob = new Blob([content]);  //用Blob对象包装一下文件流
 4 
 5   if (\'download\' in a) {
 6     a.download = fileName;// 设置下载文件的文件名
 7   }
 8   (document.body || document.documentElement).appendChild(a);
 9   a.href = window.URL.createObjectUrl(blob);;// content为后台返回的文件流
10   a.click();// 设置点击事件
11   a.remove(); // 移除a标签
12 }
13 downLoad(\'我是文件流我是文件流\', \'test.txt\')
复制代码

如果是POST请求,可以借助axios实现,配合FileReader对象。

复制代码
 1 axios.post(downloadUrl, this.searchParams, {
 2   responseType: \'blob\'
 3 }).then(res => {
 4   const blob = res.data
 5   const reader = new FileReader()
 6   reader.readAsDataURL(blob)
 7   reader.onload = (e) => {
 8     const a = document.createElement(\'a\')
 9     a.download = `表格名称.xlsx`
10     a.href = e.target.result
11     document.body.appendChild(a)
12     a.click()
13     document.body.removeChild(a)
14   }
15 }).catch(err => {
16   console.log(err.message)
17 })
复制代码

2:借助Base64实现文件的下载

对于非文本文件,也是可以借助JS下载的,比如下载图片,前端直接可以转化为base64然后下载

直接上实例代码吧,应该都看得懂,我就不多说了,

代码来自张鑫旭的关于下载的博文,可以直接查看

复制代码
 1 function download (domImg, filename) {
 2   // 创建隐藏的可下载链接
 3   let eleLink = document.createElement(\'a\');
 4   eleLink.download = filename;
 5   eleLink.style.display = \'none\';
 6   // 图片转base64地址
 7   let canvas = document.createElement(\'canvas\');
 8   let context = canvas.getContext(\'2d\');
 9   let width = domImg.naturalWidth;
10   let height = domImg.naturalHeight;
11   context.drawImage(domImg, 0, 0);
12   // 如果是PNG图片,则canvas.toDataURL(\'image/png\')
13   eleLink.href = canvas.toDataURL(\'image/jpeg\');
14   // 触发点击
15   document.body.appendChild(eleLink);
16   eleLink.click();
17   // 然后移除
18   document.body.removeChild(eleLink);
19 };
复制代码

 3:通过formData标签的方式下载,这是平安易建产品所使用的下载方式,兼容低版本浏览器

直接上代码,因为涉及到加签验签和平安的实际业务,所以看不懂就不用看了,直接上代码,用于自己以后参考

复制代码
 1 function downfile(file) {
 2   if (file == undefined || file == null) {
 3     return;
 4   }
 5   const nonce = Math.floor(Math.random() * (Math.floor(100) - Math.ceil(1))) + Math.ceil(1);
 6   const timestamp = parseInt(Date.now() / 1000);
 7   const searchParams = {
 8     storageKey: file.storageKey, // 文件系统文件key
 9     tokenType: 2, // 申请token的类型,1:上传,2:下载,5:预览
10     nonce,
11     timestamp,
12     alg: \'MD5\',
13   };
14   axios({ url: \'/docs/api/file/token/applyToken\', method: \'get\', params: searchParams })
15     .then(res => {
16       if (!res.status === 200 || !res.data) {
17         return;
18       } if (!res.data.success) {
19         const msg = res.data.msg && res.data.msg.length > 0 ? res.data.msg : \'下载失败!\';
20         message.error(msg);
21 
22       } else {
23         res = res.data || {};
24         let content = {};
25         if (res.data.contentList && res.data.contentList.length > 0) {
26           content = res.data.contentList[0];
27         }
28         return {
29           nodeUrl: content.nodeUrl,
30           token: content.token
31         }
32       }
33     }).then(({ nodeUrl, token }) => {
34       const url = `${nodeUrl}/node/download/view/${file.storageKey}`; // 文件下载路径
35       const form = document.createElement(\'form\');
36       form.setAttribute("method", "get");
37       form.setAttribute("name", "theForm");
38       form.setAttribute("target", "_self");
39       form.setAttribute(\'style\', \'display:none\');
40       form.setAttribute("action", url);
41       document.body.appendChild(form);
42 
43       const newinput_fileToken = document.createElement(\'input\');
44       newinput_fileToken.setAttribute(\'type\', \'hidden\');
45       newinput_fileToken.setAttribute(\'name\', \'fileToken\');
46       newinput_fileToken.setAttribute(\'value\', token)
47 
48       const newinput_fileName = document.createElement(\'input\');
49       newinput_fileName.setAttribute(\'type\', \'hidden\');
50       newinput_fileName.setAttribute(\'name\', \'fileName\');
51       newinput_fileName.setAttribute(\'value\', file.name)
52 
53       form.appendChild(newinput_fileToken);
54       form.appendChild(newinput_fileName);
55 
56       form.submit();
57       document.theForm.parentNode.removeChild(form);
58     });
59 }

以上是关于原生js实现文件下载的几种情况的主要内容,如果未能解决你的问题,请参考以下文章

点击li获取下标的几种方式(原生JS实现)

原生js实现文件上传

a标签调用js的几种方法

为Node.js编写组件的几种方式

不引入外部包使用原生js发送请求的几种方式

详解单页面路由的几种实现原理