在有些场景下,可以通过后端的接口进行下载,比如导出列表数据文件,但是更多的是后端已经在接口中返回了数据文件,需要前端根据已有的文件路径对文件进行下载,那么怎么实现前端下载文件呢,不同的下载方法又有什么区别呢?今天我们就来浅浅描述一下,仅代表个人观点,如果bug,请轻喷。
方式一
通过使用浏览器原生的方式下载:
window.open(*URL,name,specs,replace*)
- 仅适用于同源URL下载浏览器
默认行为下载的文件,一般不建议使用
方式二
<a href="文件url" download="下载文件别名"></a>
- download属性仅适用于同源 URL。
- 尽管 HTTP URL 需要位于同一源中,但是可以使用
blob:URL 和data:URL ,以方便用户下载使用 JavaScript 生成的内容(例如使用在线绘图 Web 应用程序创建的照片)。 - 如果 HTTP 头中的 Content-Disposition 属性赋予了一个不同于此属性的文件名,HTTP 头属性优先于此属性。
- 如果 HTTP 头属性
Content-Disposition被设置为 inline(即Content-Disposition='inline'),那么 Firefox 优先考虑 HTTP 头Content-Dispositiondownload 属性。
方式三
使用 blob: URL 和 data: URL 进行下载
// 下载图片
downloadImage(imgsrc, name, cb) {
let image = new Image()
// 解决跨域 Canvas 污染问题
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function() {
let canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
let context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
let url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
let a = document.createElement('a') // 生成一个a元素
let event = new MouseEvent('click') // 创建一个单击事件
a.download = name || 'photo' // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性
a.dispatchEvent(event) // 触发a的单击事件
cb && cb()
}
image.src = imgsrc
}
// 下载文件
downloadFile(url, name, cb) {
fetch(url).then(res => res.blob()).then(blob => {
// 将链接地址字符内容转变成blob地址
let link = document.createElement('a')
let event = new MouseEvent('click')
link.href = URL.createObjectURL(blob)
link.download = name
link.dispatchEvent(event)
cb && cb()
})
}