js下载文件

背景:最近需要根据后段返回内容生成一个txt文件(UTF-8编码)在前端可下载。尝试了几种方式,情况如下:

 

1. a标签下载

使用:

<a href="url" download="fileName"> //url为要下载的内容地址,fileName为生成的文件地址

问题:

  • url同源的情况下:浏览器直接下载
  • url不同源:浏览器则会预览:打开它能打开的文件类型,比如音频,txt文件等,而excel等文件打不开的,才会启动下载。

但我们并不希望文件被预览,而用户还需要在打开的页面上多执行一步下载的操作。所以不考虑这个办法。

2. window.open(fileUrl)

具体的使用更依赖后端,是后端已经生成好了文件而前端直接window.open(fileUrl)即可,在目前的实践中下载的情况与a标签相同,分为同源与不同源的下载。

3. FileSaver.js

一个封装好了并解决了兼容问题的库,原理是使用创建一个隐藏的a标签进行下载,并且对数据的处理已经集成好,可以下载blob,cancas等多种格式。

但我使用过程中还是没有达到要求:在mac与windows下使用FileSaver.js时生成的txt文件并不相同。

mac下生成的文件: 

输入vim -b :

windows下生成的文件:

输入vim -b :

虽然在mac与windows下都能生成txt文件,但我们可以清晰的看到在windows下生成的文件多了一个BOM头,也就是vim -b可以看到的<feff>。

原因:类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入UTF-8 BOM头。记事本等编辑器通过它来识别这个文件是否以UTF-8编码(当然即便没有UTF-8 BOM头记事本也能通过其它方式正确识别UTF-8编码)。详情见UTF-8 BOM头

而在最初后端是没有处理这个BOM头的,导致了文件可以下载,但却在上传到我们的接口时出错。

但是这是最初没有发现的问题,实际上后端改了之后忽略BOM头之后这里是没有区别的。

这里还有一个使用问题,github上的示例代码import之后只能使用saveAs函数,所以使用代码应为:

import { saveAs } from 'file-saver';
let blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
saveAs(blob, "hello world.txt");

 

4. 最终解决:生成隐藏的a标签及a.charset属性

let urlObject = window.URL || window.webkitURL || window;
let export_blob = new Blob(['你好|3']);
let a = document.createElement("a");
a.download = "example.txt";
a.href = urlObject.createObjectURL(export_blob);
a.charset="UTF-8";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);

注意:

  1. blob内容不可为空,为空将会下载整个页面;
  2. a.charset属性在html写a标签的属性里没有用,具体原因不可知;
  3. 记得生成操作完之后移除a标签避免生成多余dom。

 

总结:

  1. 如果下载的文件格式为浏览器打不开的格式,a标签的download属性就可以;
  2. 从兼容性及易用性上来说,FileSaver.js在后端改了之后其实是比js生成a标签的操作更好;
  3. 如果只是简单的项目不想加入更多依赖可以使用js生成a标签。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值