你现在这个现象:
页面显示:%PDF-1.6 %���� ...
这已经非常明确了👇
❗ 前端把 PDF 二进制流当成“文本字符串”在渲染了
也就是说:你的 axios 没有用 blob 接收,而是默认按 JSON / text 解析了
一、问题根因(关键)
你现在代码:
const res = await filePreview({ id: 20 });
const blob = new Blob([res]);
👉 这里的 res 实际上是:
- ❌ 字符串(乱码 PDF 头)
- ❌ 或被 axios 转过的错误数据
- ✅ 不是原始二进制流
二、正确写法(必须改)
✅ 第一步:接口层必须加
// api 文件
export function filePreview(params) {
return request({
url: "/xxx/preview",
method: "get",
params,
responseType: "blob", // ⚠️ 核心
});
}
✅ 第二步:若依 request.js 要确认
很多若依项目这里有坑👇
❌ 错误写法(会导致你现在问题)
return response.data;
👉 会把 blob 破坏掉
✅ 正确写法(针对 blob)
if (response.request.responseType === "blob") {
return response;
} else {
return response.data;
}
✅ 第三步:组件代码改成这样
const getFilePreview = async () => {
const res = await filePreview({ id: 20 });
const blob = new Blob([res.data], {
type: "application/pdf",
});
const url = URL.createObjectURL(blob);
path.value = url;
};
✅ 页面展示(你必须这样用)
<iframe :src="path" style="width:100%;height:100vh;" />
或者:
<embed :src="path" type="application/pdf" width="100%" height="100%" />
三、快速自检(你可以立刻验证)
✅ 正常情况 console.log 应该是:
console.log(res);
👉 你应该看到:
{
data: Blob,
headers: {...},
status: 200
}
❌ 如果你看到:
"%PDF-1.6 %����...";
👉 说明:
- ❌ responseType 没生效
- ❌ 或被拦截器改掉了
四、再给你一个“防踩坑版本”(建议直接用)
const getFilePreview = async () => {
const res = await filePreview({ id: 20 });
// ❗ 防止后端返回 JSON 错误
if (res.headers["content-type"].includes("application/json")) {
const reader = new FileReader();
reader.onload = () => {
const json = JSON.parse(reader.result);
console.error("接口错误:", json);
};
reader.readAsText(res.data);
return;
}
const blob = new Blob([res.data], { type: "application/pdf" });
path.value = URL.createObjectURL(blob);
};
五、你这个问题本质总结(记住这句话)
PDF乱码 ≠ PDF坏了
而是 前端解析方式错了
六、如果你下一步要做“更高级预览”
你现在已经解决“能显示”了,下一步可以升级👇
- iframe → vue3-pdf-app(带工具栏)
- 加用户ID水印(防传播)
- PDF 分页加载(优化性能)
- 只展示前30%(付费解锁)
如果你愿意,把你 request.js 发我,我可以帮你直接改成一套“若依标准文件流方案”,避免你后面所有下载/预览都踩坑。