时间:2021-05-25
最近在做一个文件下载的功能,这里把做的过程中用的技术和坑简要总结下。
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这两个消息头:
只要url满足上述触发的要求,那么都可以通过iframe的形式来下载
3. 代理服务处理下载
如果后端自己也能控制的话,或者后端能配合的话,可以写一个代理服务,在后端去请求文件数据,然后设置好相应的response header, 然后前端请求代理服务来做下载。
前端(假设代理服务接口是http://exampale.com/download):
const downloadUrl = 'http://exampale.com/download?url=' + encodeURIComponent(url) + '&name=xxx'; const elt = document.createElement('a'); elt.setAttribute('href', downloadUrl); elt.setAttribute('download', 'file.png'); ...后端
const url = decodeURIComponent(req.query.url);http.get(url, (response) => { res.setHeader('Content-disposition', 'attachment;filename=' + req.query.name); res.setHeader('Content-type', 'application/octet-stream'); response.pipe(res);});单文件的处理先写到这里,多文件的下载下篇在写。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
复制代码代码如下:js自动下载文件到本地functionInitAjax(){varajax;if(window.ActiveXObject){varversi
本文实例讲述了JavaScript实现写入文件到本地的方法。分享给大家供大家参考,具体如下:工作中有时需要通过JavaScript保存文件到本地,我们都知道Ja
下面,我们就分别介绍如何通过WebServices从服务器下载文件到客户端和从客户端通过WebServices上载文件到服务器。一:通过WebServices显
升级系统内核,提升性能1、输入用户名、密码登入系统,使用wget命令获取所需要的内核。2、下载文件到本地后,解压文件3、移动文件到相关目录,并切换到相关目录4、
前言在使用Linux系统的时候,我们经常需要将本地的文件上传到服务器或者从服务器上下载文件到本地,rz/sz命令很方便的帮我们实现了这个功能,但是很多linux