直接用或最快但存在兼容性问题:safari可能下载而非预览,firefox依赖已弃用插件,且不支持跨域、移动端降级及深度定制;pdf.js是唯一可控方案,支持全功能交互与跨端一致渲染。

直接用 <embed></embed> 或 <iframe></iframe> 最快,但有兼容性坑
现代浏览器基本都支持用 <embed></embed> 或 <iframe></iframe> 直接加载 PDF,不需要后端或额外库。但注意:Chrome 和 Edge 用内置 PDF 查看器,Safari 在某些版本会下载而非预览,Firefox 则依赖系统 PDF 插件(已逐步弃用)。
推荐写法:
@@@###@@@ <!-- 或 --> <iframe src="manual.pdf" width="100%" height="600px" frameborder="0"></iframe>
-
src必须是同源路径,跨域会触发 CORS 错误(如从file://直接双击打开,PDF 会加载失败) -
height建议设具体值,100vh在 iOS Safari 中可能失效 - 不要混用
<object></object>—— 它在部分 Android WebView 中 fallback 行为不可控
PDF.js 是唯一真正可控的方案
当需要翻页、缩放、搜索、打印、或确保所有设备一致渲染时,必须上 PDF.js。它把 PDF 解析成 Canvas,绕过浏览器原生限制。
最简接入方式(CDN + 静态 HTML):
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script><canvas id="pdf-canvas"></canvas><script>
pdfjsLib.getDocument('report.pdf').promise.then(pdf => {
pdf.getPage(1).then(page => {
const viewport = page.getViewport({ scale: 1.5 });
const canvas = document.getElementById('pdf-canvas');
const ctx = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({ canvasContext: ctx, viewport });
});
});
</script>
- 必须指定
pdfjsLib.GlobalWorkerOptions.workerSrc才能支持多页/大文件,否则报Missing PDF worker - 默认不支持中文搜索(需额外加载 CMap 文件),若 PDF 是扫描件,全文搜索无效
- 首次加载慢——
pdf.min.js约 1.2MB,可考虑按需动态 import
移动端点击就下载?检查 MIME 类型和响应头
如果用户点开 PDF 链接却直接下载,不是前端代码问题,而是服务端没返回正确的 Content-Type。
- 静态服务器(如 Nginx)要确保
.pdf文件返回Content-Type: application/pdf - 若用
file://协议本地测试,iOS 和部分 Android 浏览器强制下载,这是系统限制,无法绕过 - 微信内置浏览器对
<iframe></iframe>加载 PDF 支持极差,建议检测navigator.userAgent后降级为“点击下载”提示
别忽略 PDF 文件本身的问题
再好的预览方案也救不了损坏或非标准 PDF。
- 用
pdfinfo report.pdf(需安装poppler-utils)检查是否加密、是否含 XRef stream(旧版 PDF.js 不支持) - Acrobat 保存时勾选“兼容性:Acrobat 5.0(PDF 1.4)”更稳妥,避免用“优化快速 Web 查看”导出的 PDF(它拆分对象流,
PDF.js某些版本解析失败) - 小于 10KB 的 PDF 可能被某些 CDN 缓存为 text/plain,导致乱码,需手动设置缓存规则
PDF 预览看着简单,实际卡点全在边界场景:跨域、移动端 UA 差异、服务端配置、PDF 源文件质量。先跑通 <iframe></iframe>,再按需切到 PDF.js,比一开始就堆方案更省时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











