wumi_blog icon indicating copy to clipboard operation
wumi_blog copied to clipboard

js本页下载文件

Open 5Mi opened this issue 7 years ago • 1 comments

js下载文件

思路

  • 用 JavaScript 创建一个隐藏的 <a> 标签
  • 设置它的 href 属性
  • 设置它的 download 属性
  • 用 JavaScript 来触发这个它的 click 事件
fetch('http://somehost/somefile.zip').then(res => res.blob().then(blob => {
    var a = document.createElement('a');
    var url = window.URL.createObjectURL(blob);
    var filename = 'myfile.zip';
    a.href = url;
    a.download = filename;
    // 此处firefox需特殊处理  或使用dispatchEvent
    // document.body.appendChild(a);
    // a.click();
    // document.body.removeChild(a);
    //https://blog.csdn.net/qq_41960675/article/details/83782347
    a.click();
    window.URL.revokeObjectURL(url);
}));
  • createObjectURLblob 对象来创建一个 object URL(它是一个 DOMString),我们可以用这个 object URL 来表示某个 blob 对象,这个 object URL 可以用在 hrefsrc 之类的属性上。
  • revokeObjectURL 释放由 createObjectURL 创建的 object URL,当该 object URL 不需要的时候,我们要主动调用这个方法来获取最佳性能和内存使用。

ps.打开新页面下载的话window.open(url)

由于某些文件下载需要 通过请求头加token的方式 来鉴权, 即无法常规通过a标签下载 (get 请求 服务端直接返回二进制文件)

所以通过ajax方式下载, 并注意设置返回类型为 blob

// 例如 axios 中
request({
    url: '/some/download',
    method: 'get',
    responseType: "blob"
  })
// 返回的blob 直接通过 URL.createObjectURL(blob) 设置链接
// 或通过以下方法 传入 res
export function resolveBlob(res, mimeType, fileName) {
  const aLink = document.createElement('a')
  var blob = new Blob([res], { type: mimeType })
  fileName = fileName.replace(/\"/g, '')
  const url = URL.createObjectURL(blob)
  aLink.href = url
  aLink.setAttribute('download', fileName) // 设置下载文件名称
  document.body.appendChild(aLink)
  aLink.click()
  document.body.removeChild(aLink)
  URL.revokeObjectURL(url)
}

下载的是图片的话给a标签添加download属性需要该图片为同源,非同源可先请求下载再转换

getBase64Img(url){
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest()
        xhr.open('get', url, true)
        xhr.responseType = 'blob'
        xhr.onload = function() {
          if (this.status === 200) {
            let blob = this.response
            let fileReader = new FileReader()
            fileReader.onloadend = function(e) {
              let result = e.target.result
              resolve(result)
            }
            fileReader.readAsDataURL(blob)
          }
        }
        xhr.onerror = function() {
          reject()
        }
        xhr.send()
      })
}

参考

5Mi avatar Sep 15 '17 11:09 5Mi

下载文件pdf 浏览器直接预览却并非下载

先尝试给a标签设置download属性

或尝试设置文件 响应头部 Content-Disposition: attachment

5Mi avatar Sep 18 '19 03:09 5Mi