总结一下自己用过的下载方法。
方法一:
利用window.location直接下载,这个应该是最原始的、最简单的方法了。
<el-form-item>
<el-button type="primary" @click="onExport">下载</el-button>
</el-form-item>
onExport() {
const url = 'http://xx.xx.xx.xx:8080/test?testId=1'
window.location.href = url;
},
方法二:
这个方法是利用了a标签的 href 属性,但这种方法受跨域限制,不能跨域。
我使用 a 标签下载文件,都是本地文件,如代码所示是在静态资源放的文件
<el-form-item>
<el-button type="success" size="mini" @click="uploadTemplate">下载</el-button>
<a
v-show="false"
ref="excel-download-input"
href="./测试.xlsx"
download="测试.xlsx"
/>
</el-form-item>
uploadTemplate() {
this.$refs['excel-download-input'].click()
},
方法三:
这个方法是利用 iframe 标签下载文件
<el-form-item>
<el-button type="primary" @click="onExport">下载</el-button>
</el-form-item>
onExport() { // excel的导出
console.log('导出进来了')
var elemIF = document.createElement('iframe')
var url = '?testId=' + this.testId // 这里参数用的是拼接的方法
elemIF.src = this.$api.test(url) // this.$api.test(url)是拼接完整的请求url,也可以直接写地址例如elemIF.src = 'http://xx.xx.xx.xx:8080/test?testId=1'
console.log(elemIF.src)
elemIF.style.display = 'none'
document.body.appendChild(elemIF)
console.log('导出结束')
},
方法四:
这是是用 Blob 对象来下载,相比前三个方法,这个方法可以在 header 中携带 token ,也可以判断接口是否返回成功。
这里的使用方法是先在一个公共的 js 文件中封装方法
import axios from 'axios'
import { MessageBox } from 'element-ui'
import { getToken } from '@/util/auth'
// 导出Excel公用方法
export function excelExport(urlPar, fileAlias) {
axios({
method: 'get',
url: urlPar,
responseType: 'blob',
headers: {
Authorization: getToken() || ''
}
})
.then(res => {
// 这里要配你下载的类型,如果是excel,type: 'application/vnd.ms-excel' ,
// 如果是pdf文件,type:'application/pdf'
// 如果是zip文件,type:'application/zip'
// 如果是word文件,type:'application/msword'
// 其他就不一一列举了
const blob = new Blob([res.data], { type: 'application/vnd.ms-excel' })
const link = document.createElement('a')
// 如果浏览器是ie浏览器的处理方法
if (
!!window.ActiveXObject ||
'ActiveXObject' in window ||
navigator.userAgent.indexOf('Edge') > -1
) {
const fileName = fileAlias + '.xls'
navigator.msSaveBlob(blob, fileName)
} else {
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
// link.download = res.headers['content-disposition'] //下载后文件名
link.download = fileAlias + '.xls' // 下载的文件名
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
})
.catch(error => {
MessageBox({
message: '数据导出失败,请稍后再试!',
type: 'error'
})
console.log(error)
})
}
封装好方法后使用
<el-form-item>
<el-button type="primary" @click="onExport">下载</el-button>
</el-form-item>
import { excelExport } from '@/util/file' // 引入
<script>
export default {
data() {
return {
}
},
methods: {
onExport() {
const url = '?testId=' + this.testId // 这里用的是拼接参数的方法
const urlPar = this.$api.test(url) // this.$api.test(url)是拼接完整的请求url
const name = '测试'
excelExport(urlPar, name) // 第一个参数是请求地址,第二个参数是下载后的文件名
console.log('导出结束')
}
}
</script>
总结一下:
就代码的复杂程度方面上来看,前三种都相对简洁明了;但这三中方法都不能携带 token ,除此之外window.location 无法直接下载浏览器可直接预览的文件类型、 a 标签需要注意跨域问题、iframe标签要注意兼容性问题。Blob 对象方法代码虽然复杂了点,携带 token 、下载各类文件是没有问题的。不过要注意 Blob 对象在 ie10 以下是不可用的。