Vue+token+blob+实现下载文件时验证
-
之前在写
/api/download
的时候只写了这么一句话router.get('/download', (req, res) => { req.query.filename ? res.download(`./files/wuuconix/${req.query.filename}`) : res.send({ message: 'failed to download file' }) })
-
这样的话前端的下载按钮的函数只需要手动写一下
url
,然后新建一个a标签,设置以下href,再点击即可downloadFile(row) { var url=`http://${this.$ip}:3000/api/download?filename=${row.filename}` var link = document.createElement('a') try { link.href = url; } catch (error) { link.href = window.URL.createObjectURL(url); } link.click(); }
-
这样十分方便,但是带来一个致命问题,没有token验证。我们的请求头里的
authorization
只有当用axios
请求时会自动设置authorization,直接用url访问api时根本就没有这个authorization,所以当后端强制使用auth的时候,会报错router.get('/download', auth, (req, res) => { req.query.filename ? res.download(`./files/wuuconix/${req.query.filename}`) : res.send({ message: 'failed to download file' }) })
JsonWebTokenError: jwt must be provided
-
然后我就开始思考如何利用axios请求来下载文件。我先进行了简单尝试,看看res的内容是怎么样的。
const filename = row.filename this.$http.get('download', { params: { filename }}).then(res => { console.log(res) }
-
当我点击一个音乐文件时,我看到
data
中是一堆乱码。是乱码也很正常,因为后端是这样返回的。res.download(`./files/wuuconix/${req.query.filename}`)
-
于是我便在网上搜索资料,如何在利用axios下载文件。终于找到了一个可行的办法。以下是最终的代码
downloadFile(row) { const filename = row.filename this.$http.get('download', { params: { filename }, responseType: 'blob'}).then(res => { const blob = new Blob([res.data]); const link = document.createElement('a')//创建a标签 link.download = filename//a标签添加属性 link.style.display = 'none' link.href = URL.createObjectURL(blob) document.body.appendChild(link) link.click()//执行下载 URL.revokeObjectURL(link.href) //释放url document.body.removeChild(link)//释放标签 }) .catch(err => { console.log(err) }) }
router.get('/download', auth, (req, res) => { req.query.filename ? res.download(`./files/wuuconix/${req.query.filename}`) : res.send({ message: 'failed to download file' }) })
-
成功弹出下载窗口
-
这样有两个好处:一是完成了
token验证
,二是用户根本不知道文件的真实url地址
,提高的安全性。blob:http://localhost:8080/0fe40ebe-53dc-45fa-b739-734cc6b82630 //因使用blob而导致下载链接的转变
-
但是这样也有一个致命问题,就是无法处理大文件,比如我们现在点击这个高达1.64G的
进击的巨人mkv生肉
,根本就弹不出下载框。因为前端首先要进行blob解码,这么大的blob对象所需要的时间实在是太大了 -
花费了
12
秒钟才弹出下载框,这是不现实的,不可能让用户等这么久。 -
明天还需要继续探索。是否在使用axios的方式下能够处理大文件下载框加载较慢的问题。还是说还是得回到一开始url直接访问得方式,直接在url里加入token呢,这样虽然应该可行又好像不太安全,毕竟token这种东西不应该放在
明处
。
-
参考链接: