图1
最近业务上有一个下载文件的需求,需要支持png
jpg
jpeg
pdf
doc
docx
文件格式。最后使用了downloadjs
这个npm包,在使用的过程中遇到一些问题,比如:pdf文件无法正确下载,具体情况是,成功下载后的pdf文件在浏览器预览,出现上图的提示,然后用Notepad打开此pdf文件,内容是一个文档的线上URL,那么显然是不对的。
通过查看其github项目地址发现最后一次更新在2018年,而且Issues中有人提出了这个问题,想必作者已经没时间维护这个项目,下面我们来手动改造一下吧!
首先
我们通过阅读源码可以看到
图2
上图为伪代码,download函数接收3个参数data(下载的url)
strFileName(文件的名字)
strMimeType(文件的类型)
通过看第8行代码我们可以知道当在参数只存在url的时候,url为true,然后会进入19行的逻辑内,anchor.href = url
语句中,a标签的href属性赋值为url,这里浏览器会对url地址的中文进行编码,导致nchor.href.indexOf(url) === -1
,不进入此逻辑,导致无法正确下载pdf。
然后
知道了问题出在这里,我们就可以对症下药,当然解决方法不止一种,此文只介绍我使用的一种方法。
使用encodeURI() 函数
对传入的url进行url编码,地址就没有了中文,正常进入if的逻辑块,pdf便可以正确的下载,也可以直接在浏览器打开预览。
写法如下:download(encodeURI(url));
最后
现在各种格式文件已经可以正确的下载,但是由于我们对url做了编码处理,导致下载的文件名字是编码后的名字,很丑:
图3
此时我们可以改变3个地方代码解决这个问题。
1、调用方法改为download(encodeURI(url,file_name));
//传入文件名字
2、图2第8行代码改为url = !strMimeType && payload,
//取消对传入名字的限制
3、图2第21行代码改为fileName = strFileName ? strFileName : url.split("/").pop().split("?")[0];
// 如果传入了名字就使用传入的名字
提示
修改了源码后,需要将依赖文件改为本地的文件来调用。
完