11

测试说明

  • Chrome 65.0.3325.181 (64 位)
  • Chrome 69.0.3497.92 (64 位)
  • IE 11.0.9600.19002 (64 位)
  • Firefox 61.0.1 (64 位)

服务端实现下载

通过修改 HTTP 响应头,告诉浏览器这个请求回来的是个附件。以七牛为例子:

图片描述

这里需要注意两处:

  • Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
  • Access-Control-Allow-Origin 跨域资源共享设置

前端方案

通过 <a>download 属性

<a href="/path/to/img" download="name.png">下载图片</a>

抛开浏览器兼容性,还有几点限制:

  • href 所指向的地址,必须与当前网站同源,否则

    • chrome 65.0.3325.181 下测试,只能下载不能改名
    • chrome 69.0.3497.92 中已经严格遵循同源策略的限制,如果加载了非同源的内容,download 属性将失效,等效导航功能。
    • Firefox 61.0.1同上
  • 其它限制

通过 js 动态创建 <a> 并设置 download 属性

原理和限制同上,代码如下:(不支持IE)

function download(url, name) {
    const aLink = document.createElement('a')
    aLink.download = name 
    aLink.href = url 
    aLink.dispatchEvent(new MouseEvent('click', {}))
}

以导出 canvas 图片为例:

<canvas id="canvas"></canvas>
const canvas = document.getElementById('canvas')
download(canvas.toDataURL('image/png'), 'name.png')

通过 js 创建 <frame>

网上有很多文章都提到这个方案,但是这里不推荐:

  • document.execCommand('SaveAs')SaveAs 是个非标准值,主要用来兼容 ie 不支持 <a> 标签 download 属性的场景
  • window.frames["iframeName"].document 受到同源策略的影响,如果图片地址跨域,是无法访问的 <frame> 的属性和方法

参考


siwuxie
528 声望67 粉丝

404