• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

你真的会用 filesave 插件吗?

武飞扬头像
是阿臻
帮助1

前言

关于 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>> 这本书里面有解释

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhkiiga
系列文章
更多 icon
同类精品
更多 icon
继续加载