Vue+token+blob+实现下载文件时验证

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这种东西不应该放在明处


  • 参考链接:

    vue(二) vue中使用blob下载文件

    vue 带token下载——XMLHttpRequest + blob 下载文件流(vue导出excel乱码问题)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值