前端下载图片、文件的几种方式

553 阅读2分钟

在有些场景下,可以通过后端的接口进行下载,比如导出列表数据文件,但是更多的是后端已经在接口中返回了数据文件,需要前端根据已有的文件路径对文件进行下载,那么怎么实现前端下载文件呢,不同的下载方法又有什么区别呢?今天我们就来浅浅描述一下,仅代表个人观点,如果bug,请轻喷。

方式一

通过使用浏览器原生的方式下载:

window.open(*URL,name,specs,replace*)

  • 仅适用于同源URL下载浏览器默认行为下载的文件,一般不建议使用

方式二

<a href="文件url" download="下载文件别名"></a>

🌰参考

  • download属性仅适用于同源 URL
  • 尽管 HTTP URL 需要位于同一源中,但是可以使用 blob: URL 和 data: URL ,以方便用户下载使用 JavaScript 生成的内容(例如使用在线绘图 Web 应用程序创建的照片)。
  • 如果 HTTP 头中的 Content-Disposition 属性赋予了一个不同于此属性的文件名,HTTP 头属性优先于此属性。
  • 如果 HTTP 头属性 Content-Disposition 被设置为 inline(即 Content-Disposition='inline'),那么 Firefox 优先考虑 HTTP 头 Content-Dispositiondownload 属性。

方式三

使用 blob: URL 和 data: URL 进行下载

// 下载图片
downloadImage(imgsrc, name, cb) {
    let image = new Image()
    // 解决跨域 Canvas 污染问题
    image.setAttribute('crossOrigin', 'anonymous')
    image.onload = function() {
        let canvas = document.createElement('canvas')
        canvas.width = image.width
        canvas.height = image.height
        let context = canvas.getContext('2d')
        context.drawImage(image, 0, 0, image.width, image.height)
        let url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
        let a = document.createElement('a') // 生成一个a元素
        let event = new MouseEvent('click') // 创建一个单击事件
        a.download = name || 'photo' // 设置图片名称
        a.href = url // 将生成的URL设置为a.href属性
        a.dispatchEvent(event) // 触发a的单击事件
        cb && cb()
    }
    image.src = imgsrc
}
// 下载文件
downloadFile(url, name, cb) {
    fetch(url).then(res => res.blob()).then(blob => { 
        // 将链接地址字符内容转变成blob地址
        let link = document.createElement('a')
        let event = new MouseEvent('click')
        link.href = URL.createObjectURL(blob)
        link.download = name
        link.dispatchEvent(event)
        cb && cb()
    })
}