序:
在實(shí)現(xiàn)文件的下載,采用 a 標(biāo)簽,會(huì)出現(xiàn)圖片,沒有進(jìn)行下載,而是,在當(dāng)前頁面打開了圖片。
導(dǎo)致原因: ·a標(biāo)簽,有 download 屬性,可以實(shí)現(xiàn)下載 同源文件( ip 和 端口 相同),當(dāng)圖片不同源 時(shí),點(diǎn)擊下載,會(huì)在當(dāng)前窗口直接打開圖片,而不是進(jìn)入下載狀態(tài)。
1. 后端返回文件 url (a標(biāo)簽)
1.1 沒有圖片的情況
<template>
<div>
<a-modal v-model:visible="props.visible" title="DownloadFile">
<div class="down-load-file" v-for = "(item, index) in fileList" :key="index">
<h4>{{item.fileType}}: </h4>
<a :href="item.fileUrl" download>{{item.fileName}}</a>
</div>
</a-modal>
</div>
</template>
1.2 下載遠(yuǎn)程圖片
1.2.1 圖片地址后加"?response-content-type=application/octet-stream"
使用contentType訪問頁面的時(shí)候,瀏覽器就會(huì)開啟下載框?qū)ζ鋬?nèi)容進(jìn)行下載
<template>
<div>
<a-modal v-model:visible="props.visible" title="DownloadFile">
<div class="down-load-file" v-for = "(item, index) in fileList" :key="index">
<h4>{{item.fileType}}: </h4>
<span class="opr-btn-normal" @click="download(item.fileUrl)">{{item.fileName}}</span>
</div>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { onMounted, createVNode, reactive, defineComponent, ref } from 'vue';
// 列表
const fileList = ref<any[]>([]);
const download = (url) => {
// 處理圖片下載
let newstring= url.substring(url.length-4, url.length);
if(['.png', '.jpg','jpeg', '.bmp', '.gif', 'webp', '.psd', '.svg', 'tiff'].indexOf(newstring) !== -1) {
url = url + '?response-content-type=application/octet-stream'
}
let a = document.createElement("a");
a.setAttribute("href", url);
a.setAttribute("download",'');
a.setAttribute("target", "_blank");
let clickEvent = document.createEvent("MouseEvents");
clickEvent.initEvent("click", true, true);
a.dispatchEvent(clickEvent);
}
</script>
<style lang="less">
.opr-btn-normal {
color: #007df1;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
.down-load-file {
display: flex;
>span {
margin-left: 10px;
}
}
</style>
1.2.2、通過 canvas 方式 保存圖片
<script>
/**
* 下載圖片
* @param {string} imgsrc 圖片地址
*/
downloadIamge(imgsrc) {
// 新建圖片對象
let image = new Image();
// 解決跨域 Canvas 污染問題
image.setAttribute("crossOrigin", "anonymous");
// 圖片加載
image.onload = function() {
// 新建 canvas標(biāo)簽
let canvas = document.createElement("canvas");
// 設(shè)置 canvas寬高
canvas.width = image.width;
canvas.height = image.height;
// 添加 canvas畫筆
let context = canvas.getContext("2d");
// 繪制圖片
context.drawImage(image, 0, 0, image.width, image.height);
// 得到圖片的 base64 編碼
let url = canvas.toDataURL("image/png");
// 新建 a標(biāo)簽
let a = document.createElement("a");
// 新建點(diǎn)擊事件
let event = new MouseEvent("click");
// 將圖片的 base64 編碼,設(shè)置為 a標(biāo)簽的地址
a.href = url;
// 觸發(fā)點(diǎn)擊事件
a.dispatchEvent(event);
};
// 將圖片地址 設(shè)置為 傳入的參數(shù) imgsrc
image.src = imgsrc;
};
/**
* 下載方法
* @param {string} filepath 文件地址
*/
downloads(filepath) {
// isImageFile():自定義函數(shù),根據(jù)*后綴*判斷是否是圖片
if (isImageFile(filepath)){
this.downloadIamge(filepath)
} else {
this.downloadFile(filepath)
}
};
</script>
2. 后臺(tái)返回文件流時(shí),用 blob 對象下載文件
參考文章來源:http://www.zghlxwxcb.cn/news/detail-402340.html
// res 是返回的文件流,type 是文件MIME類型, fileName 是給下載的文件一個(gè)名稱
const blobDownloadFile = (res: any, type: string, fileName: string) => {
const blob = new Blob([res], {
type: type
})
const a = document.createElement('a')
const URL = window.URL || window.webkitURL
const herf = URL.createObjectURL(blob)
a.href = herf
a.download = fileName
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
window.URL.revokeObjectURL(herf)
}
blobDownloadFile(url, 'text/plain', '測試')
3. JSZip 庫以壓縮包下載文件
JSZip庫
組件中使用文章來源地址http://www.zghlxwxcb.cn/news/detail-402340.html
import { onMounted } from 'vue'
import JSZip from 'jszip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
let dowloadZip: JSZip
const urlToPromise = (url: string) =>
new Promise((resolve, reject) => {
JSZipUtils.getBinaryContent(url, (err: any, data: unknown) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
// 添加文件
dowloadZip.file(item.fileName, urlToPromise(item.fileUrl), { binary: true })
// .generateAsync() 生成一個(gè) zip 文件
dowloadZip
.generateAsync({ type: 'blob' })
.then(
(blob) => {
// saveAs(blob, "測試.zip"); 直接在瀏覽器打成 測試.zip 包并下載
saveAs(blob, '測試.zip')
},
(e) => {
console.log(e)
}
)
// 在 DOM 掛載之后創(chuàng)建 JSZip 實(shí)例
onMounted(() => {
dowloadZip = new JSZip()
})
到了這里,關(guān)于vue3利用 a 標(biāo)簽,文件流,JSZip 壓縮包,實(shí)現(xiàn)文件下載的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!