以前項目中的一個文件上傳後下載的需求,後端是把文件存在文件服務器,而後返回給前端一個文件地址
拿到url後使用a標籤下載,可是對於文件是圖片,.txt或者 .pdf這些瀏覽器能夠直接打開的文件,沒有下載,而是直接在當前頁面打開了,緣由是由於url不是同源的 前端
blob:URLs
和
data:URLs
的形式
blob:URLs
和data:URLs
來下載圖片的代碼// data: URLs方式
downloadByData (url) {
let image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.src = url
image.onload = () => {
let canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
let ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
let ext = image.src.substring(image.src.lastIndexOf('.')+1).toLowerCase()
let dataURL = canvas.toDataURL('image/' + ext)
download(dataURL)
}
},
// blob: URLs方式
downloadByBlob (url) {
let image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.src = url
image.onload = () => {
let canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
let ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
canvas.toBlob((blob) => {
let url = URL.createObjectURL(blob)
download(url)
// 用完釋放URL對象
URL.revokeObjectURL(url)
})
}
},
download (href, name = 'pic') {
let eleLink = document.createElement('a')
eleLink.download = name
eleLink.href = href
eleLink.click()
eleLink.remove()
}
複製代碼
data: URLs
方式是先建立一個圖片,而後用canvas繪製該圖片,而後使用canvas.toDataURL
得到Data URLs
blob: URLs
方式也差很少,使用canvas.toBlob
獲得blob,而後使用URL.createObjectURL
建立URL對象
代碼中有設置圖片的crossOrigin屬性image.setAttribute('crossOrigin', 'anonymous')
,由於圖片跨域,canvas的toDataURL和toBlob都會報錯拿不到結果ios
可是上面的方法對於txt和pdf文件就不行了nginx
直接經過ajax請求,get到文件的blob數據,而後使用blob:URLs
的形式下載ajax
downloadByGetBlob (url) {
axios.get(url, {responseType: 'blob'}).then(res => {
let blob = res.data
let url = URL.createObjectURL(blob)
download(url)
// 用完釋放URL對象
URL.revokeObjectURL(url)
})
}
複製代碼
這種方式須要注意跨域問題,須要後端服務器支持canvas
location /images {
proxy_redirect off;
proxy_pass https://www.yourfile.com;
}
複製代碼