加了統一鑑權以後 如果把下載接口也攔截了 且前端使用的是a標籤 可以用如下方法解決
替換調請求url和請求方式 , 方式一和方式二任意註釋一個就可以運行了
方式1用的是原生的XmlHttpRequest 方式2用的是vue常用的axios
這兩種方式都可以很方便的加入header
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>a標籤觸發ajax</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<a href="#" class="a_post">發起POST請求</a>
<script>
//方式1
$(".a_post").on("click",function(event){
event.preventDefault();//使a自帶的方法失效,即無法調整到href中的URL
var url='http://localhost:8050/file/export/snapEventVO'; //請求的URl
var xhr = new XMLHttpRequest(); //定義http請求對象
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send();
xhr.responseType = "blob"; // 返回類型blob
xhr.onload = function() { // 定義請求完成的處理函數,請求前也可以增加加載框/禁用下載按鈕邏輯
if (this.status===200) {
var blob = this.response;
//alert(this.readyState);
//alert(xhr.getAllResponseHeaders());
console.log(xhr.getResponseHeader("content-disposition"))
let temp = xhr.getResponseHeader("content-disposition").split(";")[1].split("filename=")[1];
var fileName = decodeURIComponent(temp);
//var hh = xhh.getResponseHeader("fileName");
//var fileName = this.response.headers["content-disposition"].split(";")[1].split("filename=")[1];
//console.log("fileName="+fileName)
//console.log(xhr.getResponseHeader("content-disposition"))
var reader = new FileReader();
reader.readAsDataURL(blob); // 轉換爲base64,可以直接放入a標籤href
reader.onload=function (e) {
console.log(e); //查看有沒有接收到數據流
// 轉換完成,創建一個a標籤用於下載
var a = document.createElement('a');
a.download=fileName+".xlsx"; //自定義下載文件名稱
a.href = e.target.result;
$("body").append(a); // 修復firefox中無法觸發click
a.click();
//$(a).remove();
}
}
else{
alert("出現了未知的錯誤!");
}
}
});
//方式2
/*$(".a_post").on("click",function(event){
event.preventDefault();//使a自帶的方法失效,即無法調整到href中的URL
axios({
method: 'post',
url: "http://localhost:8050/file/export/snapEventVO",
responseType: 'blob'
}).then((res) => {
const link = document.createElement('a')
let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'});
//獲取heads中的filename文件名
var aa = res.headers["content-disposition"]
let temp = res.headers["content-disposition"].split(";")[1].split("filename=")[1];
var fileName = decodeURIComponent(temp);
console.log(fileName)
link.style.display = 'none'
link.href = URL.createObjectURL(blob);
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}).catch(error => {
console.log(error)
})
});
*/
</script>
</body>
注意 如果涉及跨域問題 是無法直接拿到content-disposition中的fileName的
需要在服務端添加Access-Control-Expose-Headers指定允許訪問的header
java代碼如下 其他語言同理
response.setHeader("Access-Control-Expose-Headers","Content-Disposition");//指定Content-Disposition可以讓前端獲取