<template> <el-upload ref="single-upload" :action="uploadConf.action" :multiple="false" :headers="uploadConf.headers" :data="uploadConf.data" :before-upload="onBeforeUpload" :on-progress="onProgress" :on-success="onSuccess" :show-file-list="false" > <slot></slot> </el-upload> </template> <script> import getUploadSign from "@/api"; import generateId from 'nanoid/generate'; // 随机文件名 export default { name: "CSingleUpload", components: {}, props: { accept: { type: Array, default: () => [] }, maxFileSize: { type: Number, default: 20 }, files: { type: Array, default: () => [] } }, data() { return { fileList: [], uploadConf: { action: "", headers: {}, data: {}, fileList: [] }, fileObj: null, }; }, methods: { // 上传前拦截 async onBeforeUpload(file) { const { size, type, name, uid } = file; const oldName = name; const nameArr = oldName.split('.'); const fileName = nameArr[0] + '-' + generateId('0123456789qwertyuiopasdfghjklzxcvbnm', 15) + '.' + nameArr[1]; // 判断文件类型 // const isFileType = this.accept.some(accept => accept === type); // if (!isFileType) { // this.$message.warning(`该文件(${oldName})类型(${type})不支持`); // return Promise.reject(); // } // 判断文件大小 const KB = size / 1024; const MB = KB / 1000; if (MB > this.maxFileSize) { let unit = `${this.maxFileSize}m`; if (this.maxFileSize < 1) { unit = `${Math.floor(this.maxFileSize * 1000)}kb`; } this.$message.warning(`该文件(${oldName})大小已超过限制(${unit})`); return Promise.reject(); } // 请求签名 const sign = await getUploadSign({ dir: type.split('/')[0], key: fileName }); // 显示上传对象 this.fileObj = { type, size, uid, oldName, name: fileName, url: (window.URL || window.webkitURL).createObjectURL(file), ossUrl: `${sign.host}/${sign.dir}${fileName}`, progress: 0, isUpload: false }; // 填充签名参数 this.uploadConf.data = { key: `${sign.dir}${fileName}`, policy: sign.policy, OSSAccessKeyId: sign.accessid, success_action_status: 200, signature: sign.signature, callback: sign.callback, }; this.uploadConf.action = sign.host; this.uploadConf.headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET, POST" }; // return Promise.reject(); }, // 更新文件上传进度 onProgress(event) { const { percent } = event; this.$emit("on-progress", percent); }, // 更新文件上传成功状态 onSuccess(response, file) { this.$emit('successCBK', this.fileObj.ossUrl, this.fileObj); }, } }; </script> <style lang="less" scoped> </style>
这种下载文件的方式兼容性比较好,一般不会出现跨域问题,如果使用的是axios封装的方法下载可能跨域。
export function downloadFile2(url, filename) { /** * 下载文件 * 原理:通过获取文件内容转译为二进制,传给创建a标签下载 * @param url 文件地址url * @param filename 下载保存的名字 */ var downloadFileBya = function (fileName, content) { var aLink = document.createElement('a'); var blob = new Blob([content]); var evt = document.createEvent("MouseEvents"); evt.initEvent("click", true, true); if (fileName) { aLink.download = fileName; } aLink.target = "_blank"; aLink.href = URL.createObjectURL(blob); aLink.dispatchEvent(evt); } // 拿文件的名字 var fileNameFromHeader = function (disposition) { if (disposition) { let index = disposition.lastIndexOf("/"); return decodeURIComponent(disposition.substring(index + 1, disposition.length)); } return "undefine_file"; } var xhr = new XMLHttpRequest(); xhr.withCredentials = false; xhr.responseType = "blob"; xhr.open('GET', url, true); xhr.onload = function () { if (this.status == 200) { // var blob = this.response; var donwloadName = filename != undefined ? filename : fileNameFromHeader(xhr.responseURL); downloadFileBya(donwloadName, xhr.response); } else { console.error("请求下载文件错误,请求错误码:" + this.status); return false; } } xhr.send(); }