一、前言
先情景还原:
我们有一个打印pdf的接口,是 get
形式的,传参是用的 url
传参,如:
https://www.xxx.com/api/a/b/downloadPdf?ssyd=202501&userUid=123456
以前能正常使用的,但自从统一认证授权更新后,对于访问所有的请求都要进行授权,否则就请求不了。
授权是放在请求的 Header
里的,参数名为:Authorization
,如:
按理说,改起来应该很快,但是
:
- 木有源码;
- 是webpack打包的,那个反编译惨烈程度可想而知;
因此给修复工作增添了很多难度。心想:
要是
window.location.href
跳转时,能带个header
参数Authorization
,不就完美解决了吗?
完美,说干就干!
但是,我很负责人地告诉你,这种思路是行不通的,因为 window.location.href 不支持携带 header 参数
OMG,刚燃起来的希望之火,瞬间熄灭~
兄弟,我知道你很急,但你先别急:我们可以曲线救国,实现想要的效果呀
二、解决方案
1.思路解析
先这样,再那样,然后那样,最后这样,不就完成了嘛!
开个玩笑,思路如下:
我们先用
ajax
携带Authorization
头去请求url
,然后把返回的文件流
,下载
到客户端。
还有个条件:你得能用代码取到
access_token
,不然也行不通。
取不到 access_token
的可以节省点时间,就别往下看了。
2.实操
原代码处:
//可以看到被 webpack 打包得快连爹妈都不认识了
window.location.href="".concat(g["a"].apiHost,"/api/a/b/downloadPdf?ssyd=")+this.ssyd+"&userUid="+this.userUid;
改为:
//可以看到把原本 href 的值设置成了一个变量
let url = "".concat(g["a"].apiHost,"/api/a/b/downloadPdf?ssyd=")+this.ssyd+"&userUid="+this.userUid;
let authToken = 'Bearer '+this.$store.state.token.access_token;
// 创建 XMLHttpRequest 对象 (这里我们用原生js实现,当然你也可以用 fetch 等)
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
// 设置 Authorization 请求头
xhr.setRequestHeader('Authorization', authToken);
// 指定响应类型为 blob(二进制数据)(因为这里我们返回的是文件,你可以根据你的实际情况设置)
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
// 从响应头获取文件名(需要服务器返回 Content-Disposition 头)
var contentDisposition = xhr.getResponseHeader('Content-Disposition');
var fileName = 'default_filename.ext'; // 默认文件名
// 如果服务器返回了文件名,则提取(示例格式:attachment; filename="file.txt")
if (contentDisposition) {
var fileNameMatch = contentDisposition.match(/filename="?(.+?)"?(;|$)/);
if (fileNameMatch && fileNameMatch[1]) {
fileName = fileNameMatch[1];
}
}
// 创建 Blob 对象并下载
var blob = new Blob([xhr.response], { type: xhr.response.type });
var downloadUrl = window.URL.createObjectURL(blob);
// 创建隐藏的 <a> 标签触发下载(这里是重点!!!)
var a = document.createElement('a');
a.href = downloadUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
// 清理资源
window.URL.revokeObjectURL(downloadUrl);
document.body.removeChild(a);
} else {
console.error('请求失败:', xhr.statusText);
}
};
xhr.onerror = function() {
console.error('请求发生错误');
};
xhr.send();
好了,运行一下,看看效果:
完美!!!
这时候你肯定要问了:不是没有源码吗,那你怎么改的?
阿西巴
,我改的是webpack打包后的代码:
都看到这里了,各位帅哥/美女,不管有用没用,都帮忙点个赞呗,❤️谢谢~
-
Author
- 吴所畏惧 2025.03.06