Window下载
实现原理:直接用浏览器访问下载链接,唤起浏览器下载功能
1 2 3
| window.location.href = '下载链接';
window.open('下载链接');
|
缺点:无法(从前端)自定义下载文件名,下载可预览文件(图片,音乐、视频等)时,会跳转新的界面
A标签下载
实现原理:创建一个a标签,然后点击它,即把下面的标签用js创建出来
1
| <a href="下载链接" download="文件名(如:a.zip)">下载</a>
|
a标签download+url
1 2 3 4 5 6 7 8
| const a = document.createElement('a') a.href = '下载链接' a.download = '文件名' a.style.display = 'none' a.target = 'downloadFile' document.body.appendChild(a) a.click() document.body.removeChild(a)
|
缺点:下载可预览文件时,会跳转新的界面,对于跨域请求download属性会失效,也就是说无法自定义下载文件名
window.URL+blob
下载文件
由于上面是方法会打开新的界面,所以我们需要对下载链接进行一些处理,比如转为blob格式:
1 2 3 4 5 6 7 8 9 10
| const blob = await fetch('下载链接').then(res => res.blob()) content = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = content a.download = '文件名' document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(content)
|
也可以用ajax请求转为blob格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const x = new window.XMLHttpRequest() x.open('GET', '下载链接', true) x.responseType = 'blob' x.onload = () => { const content = window.URL.createObjectURL(x.response) const a = document.createElement('a') a.href = content a.download = '文件名' document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(content) } x.send()
|
自然也可以发送axios请求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| axios({ method: 'get', url: '下载链接' responseType: 'blob', }).then((res) => { if (res && res.status === 200) { const content = window.URL.createObjectURL(new Blob([response.data])); const a = document.createElement('a') a.href = content a.download = '文件名' document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(content) } }
|
缺点:需要对下载链接进行请求,将下载的文件转为blob格式,所以自然少不了跨域问题,并且blob格式无法在手机端浏览器下载,所以建议和上面的配合使用,手机端用上面的url方法下载,电脑端用blob
下载文字
如果是文字的话,则无需再发送请求,可直接将文字转为blob格式
1 2 3 4 5 6 7 8 9 10
| const blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
content = window.URL.createObjectURL(blob) const a = document.createElement('a') a.href = content a.download = '文件名' document.body.appendChild(a) a.click() document.body.removeChild(a) window.URL.revokeObjectURL(content)
|
From表单下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const url = '下载地址' const form = document.createElement('form') form.style.display = 'none' form.setAttribute('target', '_blank') form.setAttribute('method', 'get') form.setAttribute('action', url)
const input = document.createElement('input')
input.setAttribute('type', 'hidden') input.setAttribute('name', '请求参数名'); input.setAttribute('value', '请求参数值');
form.appendChild(input) document.body.appendChild(form) form.submit() document.body.removeChild(form)
|
下载可预览文件时,会跳转新的界面
Iframe下载
iframe下载不会出现向a标签那样的跳转问题,但是iframe兼容性较差,反正我在测试中没成功过
1 2 3 4 5 6 7 8
| const url = '下载地址'; const iframe = document.createElement('iframe'); iframe.src = url; iframe.style.display = 'none'; iframe.onload = function() { document.body.removeAttribute(iframe); } document.body.appendChild(iframe);
|
Canvas下载图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const url = '图片下载地址' const a = document.createElement('a') a.setAttribute('download', '文件名称') const image = new Image()
image.src = url + '?timestamp=' + new Date().getTime()
image.setAttribute('crossOrigin', 'Anonymous') image.onload = () => { const canvas = document.createElement('canvas') canvas.width = image.width canvas.height = image.height const ctx = canvas.getContext('2d') ctx.drawImage(image, 0, 0, image.width, image.height) const extension = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase() const base64Url = canvas.toDataURL('image/' + extension, 1)
a.href = base64Url a.click() }
|
缺点:同样需要处理跨域问题
FileSaver下载文件
使用FileSaver下载文件时仍然存在跨域问题
下载:
1 2 3 4
| npm install file-saver --save
# 或者: bower install file-saver
|
引入:
1
| import fileSaver from 'file-saver'
|
下载文字
1 2
| var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"}); fileSaver.saveAs(blob, "hello world.txt");
|
下载图片(画布)
1 2 3 4
| var canvas = document.getElementById("canvasid"); canvas.toBlob(function(blob) { fileSaver.saveAs(blob, "image.png"); });
|
下载网络资源
1
| fileSaver.saveAs('地址', '名称')
|
下载文件(file)
1 2
| var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"}); fileSaver.saveAs(file);
|
下载文件(blob)
1
| fileSaver.saveAs(blob, '文件名')
|
示例
转为blob格式的方法,上面已经写了很多个了,这里取其中一个做示范:
1 2
| const blob = await fetch('下载链接').then(res => res.blob()) fileSaver.saveAs(blob, '文件名')
|