• 你真的会用 filesave 这个插件吗?


    前言

    关于 FileSaver 这个插件不少人都知道是用来保存文件的, 但是你可能不知它会在通过url保存文件的时候通过 HEAD 的请求方法来确认资源是否真正可以访问。当HEAD方法成功之后,接下来才会真的去执行下载逻辑; 下面是插件的源码, 在 corsEnabled 函数里面会发送一个 HEAD 方法

    
    function corsEnabled (url) {
      var xhr = new XMLHttpRequest()
      // use sync to avoid popup blocker
      xhr.open('HEAD', url, false)
      try {
        xhr.send()
      } catch (e) {}
      return xhr.status >= 200 && xhr.status <= 299
    }
    
    
    function saveAs (blob, name, opts) {
        var URL = _global.URL || _global.webkitURL
        var a = document.createElement('a')
        name = name || blob.name || 'download'
    
        a.download = name
        a.rel = 'noopener' // tabnabbing
    
        // TODO: detect chrome extensions & packaged apps
        // a.target = '_blank'
    
        if (typeof blob === 'string') {
          // Support regular links
          a.href = blob
          if (a.origin !== location.origin) {
            corsEnabled(a.href)
              ? download(blob, name, opts)
              : click(a, a.target = '_blank')
          } else {
            click(a)
          }
        } else {
          // Support blobs
          a.href = URL.createObjectURL(blob)
          setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s
          setTimeout(function () { click(a) }, 0)
        }
      }
    
      // Use msSaveOrOpenBlob as a second approach
      : 'msSaveOrOpenBlob' in navigator
      ? function saveAs (blob, name, opts) {
        name = name || blob.name || 'download'
    
        if (typeof blob === 'string') {
          if (corsEnabled(blob)) {
            download(blob, name, opts)
          } else {
            var a = document.createElement('a')
            a.href = blob
            a.target = '_blank'
            setTimeout(function () { click(a) })
          }
        } else {
          navigator.msSaveOrOpenBlob(bom(blob, opts), name)
        }
      }
    

    错误使用

    想象一下你这个时候通过一个 url 来下载一个表格, url 上面有一些查询参数, 当这个后台接收到请求之后,会查询数据库, 经过一系列的逻辑处理终于打成目标, 可以导出一个表格了!!! 结果呢, 卧槽竟然只是一次HEAD 方法试探, 没有办法, 服务端还是要再来一遍之前的逻辑, 把结构返回给后续的GET 方法, 所以如果你需要下载的资源是实时生成的可能不太适合使用 filesave 直接下载, 可以通过 ajax 发送请求, 然后将返回的数据导出。

    正确使用

    像图片这种资源, 还有前端导出表格就比较适合 FileSaver 这个插件

    适合我使用场景的demo

    这里我需要一个下载状态, 所以通过发送一个get请求, 然后将返回的数据稍作处理进行导出表格, 并不是直接通过a标签导出的

    export default (opt = { url: '', method: 'get' }, fileName) => {
      return request({
        ...opt,
        responseType: 'blob'
      }).then(res => {
        const link = document.createElement('a')
        link.href = URL.createObjectURL(res.data)
        link.download = fileName
        link.click()
        return true
      })
    }
    

    解释

    HEAD 方法: HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等; 在<<图解http>> 这本书里面有解释

  • 相关阅读:
    2017-2018-2 20165207 实验四《Android开发基础》实验报告
    2017-2018-2 20165207 实验三《敏捷开发与XP实践》实验报告
    20165207 第九周学习总结
    20165328 实验四《Andriid应用开发》实验报告
    20165328 第十二周课上补做
    20165328 课下作业补做
    20165328 第九周学习总结
    2017-2018-2 20165328 实验三《敏捷开发与XP实践》实验报告
    20165328 结对编程第二周整体总结
    20165328课上补做
  • 原文地址:https://www.cnblogs.com/shiazhen/p/16330281.html
Copyright © 2020-2023  润新知