首页 > 语言 > JavaScript > 正文

通过JavaScript下载文件到本地的方法(单文件)

2024-05-06 15:41:42
字体:
来源:转载
供稿:网友

最近在做一个文件下载的功能,这里把做的过程中用的技术和坑简要总结下。

1. 单文件下载(a标签)

同源单文件

针对单文件的情况下,同源的文件,可以通过 < a> 标签的 download 属性下载文件

 const elt = document.createElement('a'); elt.setAttribute('href', url); elt.setAttribute('download', 'file.png'); elt.style.display = 'none'; document.body.appendChild(elt); elt.click(); document.body.removeChild(elt);

但是这个方案并不适用于非同源的资源,此时它相当于普通的超链接,点击会跳转到资源页面,而不是下载。

非同源图片

如果不存在CORS问题, 可以借助Blob实现下载(构造xhr请求文件地址, 以Blob的形式接收Response):

function downloadWithBlob(url) { fetch(url).then(res => res.blob().then(blob => {  var a = document.createElement('a');  var url = window.URL.createObjectURL(blob);  var filename = 'file.png';  a.href = url;  a.download = filename;  a.click();  window.URL.revokeObjectURL(url); }));}

如果存在CORS问题,可以考虑使用 canvas 将图片转换成 base64 编码之后再通过 标签的 download 属性下载

function downloadPic(url) { const img = new Image; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); img.onload = function() {  canvas.width = this.width;  canvas.height = this.height;  ctx.drawImage(this, 0, 0);  const elt = document.createElement('a');  elt.setAttribute('href', canvas.toDataURL('image/png'));  elt.setAttribute('download', 'file.png');  elt.style.display = 'none';  document.body.appendChild(elt);  elt.click();  document.body.removeChild(elt); }; img.crossOrigin = 'anonymous'; img.src = url;}

2. 单文件下载(iframe)

iframe方式是在页面内隐藏iframe, 然后将下载地址加载到iframe中, 从而触发浏览器的下载行为

 const iframe = document.createElement('iframe'); iframe.src = url; iframe.style.display = 'none'; document.body.appendChild(iframe);

但是这里发现,即使是同域的图片,也无法完成下载,这是为啥呢?

这里就有个上面的a链接下载没有提到的问题:什么样的链接才能触发浏览器的下载:

url如何触发浏览器自动下载

一个url能否触发浏览器自动下载,主要看该请求响应头response header是否满足,一般是看Content-Disposition和Content-Type这两个消息头:

response header中指定了Content-Disposition为attachment,它表示让浏览器把消息体以附件的形式下载并保存到本地 (一般还会指定filename, 下载的文件名默认就是filename) response header中指定了Content-Type 为 application/octet-stream(无类型) 或 application/zip(zip包时)等等。(其中 application/octet-stream表示http response为二进制流(没指定明确的type), 用在未知的应用程序文件,浏览器一般不会自动执行或询问执行。浏览器会像对待 设置了HTTP头Content-Disposition 值为 attachment 的文件一样来对待这类文件)
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选