一、前言
项目中遇到一些资源下载的需求,以往都是用简单的window.open()来解决,在特殊情况下并不能达到预期的效果,踩了很多坑;这里整理了一些项目中遇到过的关于下载资源的一些方法,包括不同格式和不同的开发环境。
二、技能点
URL.createObjectURL
静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
FileSaver
FileSaver.js 是一款基于 HTML5 完成文件保存的插件,它可以帮我们直接从网页中导出多种格式文件。 同时对于那些本身不支持 HTML5 W3C saveAs() FileSaver 接口的浏览器,FileSaver.js 也提供了支持。 使用 FileSaver.js 可以让 Web 应用完美的生成文件,或者保存那些不应该发送到外部服务器的敏感息。 是一种简单易用的浏览器端文件保存方案。
jsPDF
jsPDF 是一个基于 HTML5 的客户端解决方案,用于生成各种用途的 PDF 文档
XMLHttpRequest
三、Web下载
web端基本没有什么限制,无非要注意的就是浏览器兼容与文件格式这2个方面,这里展示几个比较常用的方法
通过 URL.createObjectURL 创建一个新的 URL 对象来进行下载
- 这里的fetch目的是为了用合理的方式来跨网络异步获取资源
- Blob对象表示一个不可变、原始数据的类文件对象
function handleDownload(url, filename) {
return fetch(url).then(res => res.blob().then(blob => {
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = filename || '_t';
a.target = '_blank'
a.click();
window.URL.revokeObjectURL(url);
}))
}
- 这里加上一个Blob需要设置头部的情况
function handleDownload(url) {
const blob = new Blob([url], {
type:
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"
});
const url = URL.createObjectURL(blob);
const el = document.createElement("a");
document.body.appendChild(el);
el.href = url;
el.download = "提现记录.xlsx";
el.target = "_blank";
el.click();
document.body.removeChild(el);
}
通过 form 方式下载
function handleDownload(url) {
let form = document.createElement('form');
form.action = src;
document.body.appendChild(aElement)
form.submit()
}
canvas 转图片下载
- 这里的 canvas.toDataURL 接收两个参数,图片格式和图片质量,具体参照 developer.mozilla.org/zh-CN/docs/…
let src = canvas.toDataURL("image/jpg", 1);
let image = new Image();
image.src = src;
let url = image.src.replace(
/^data:image\/[^;]/,
"data:application/octet-stream"
);
let a = document.createElement("a");
a.download = "image_t.jpg";
a.href = url;
document.body.appendChild(a);
a.click();
a.remove();
canvas 转pdf下载
- jspdf 插件官网 parall.ax/products/js…
const { width, height } = canvas;
const url = canvas.toDataURL("image/jpeg", 1.0);
const pdfWidth = ((width + 10) / 2) * 0.75;
const pdfHeight = ((height + 500) / 2) * 0.75;
const displayWidth = pdfWidth;
const displayHeight = (height / 2) * 0.75;
const pdf = new jspdf("", "pt", [pdfWidth, pdfHeight]);
pdf.addImage(url, "jpeg", 0, 0, displayWidth, displayHeight);
pdf.save("pdf_t.pdf");
XMLHttpRequest
export function downloadPDF({ url, fileName }) {
const xmlHttp = new XMLHttpRequest()
xmlHttp.open('GET', url, true)
xmlHttp.responseType = 'blob'
xmlHttp.onload = function(res) {
if (this.status == 200) {
const blob = this.response
DownLoadPDPFromBlob(blob, fileName)
}
}
xmlHttp.send()
}
export function DownLoadPDPFromBlob(blob, fileName) {
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else {
const eleLink = document.createElement('a')
eleLink.download = fileName
eleLink.style.display = 'none'
eleLink.href = URL.createObjectURL(blob)
eleLink.target = '_new'
document.body.appendChild(eleLink)
eleLink.click()
document.body.removeChild(eleLink)
window.URL.revokeObjectURL(eleLink.href)
}
}
四、移动端下载
移动端下载的限制很大,基本上浏览器都会要求用户同意才能进行下载,加上ios用户的safari浏览器除了图片格式其他基本无法正常下载;以上web端的方法都无法在移动端使用,移动端资源下载本身就是个大坑;这里找到一个插件,算是能完成图片的下载。
FileSaver