跳转至

你现在这个现象:

页面显示:%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 发我,我可以帮你直接改成一套“若依标准文件流方案”,避免你后面所有下载/预览都踩坑。