直接用最快但需http环境且不兼容旧浏览器;pdf.js跨平台可控但需配置worker并自行实现ui;ios safari和微信需降级为链接跳转或强制使用pdf.js。

用 <iframe></iframe> 直接嵌入 PDF 最快,但有兼容性限制
现代浏览器(Chrome、Edge、Firefox、Safari 15.4+)原生支持直接通过 <iframe src="xxx.pdf"></iframe> 渲染 PDF,无需后端或额外库。但注意:file:// 协议下(本地双击 HTML 打开)多数浏览器会拒绝加载 PDF,必须通过本地服务器(如 python3 -m http.server)或部署到 HTTP/HTTPS 环境才能生效。
常见错误现象:Failed to load resource: net::ERR_BLOCKED_BY_CLIENT 或空白 iframe —— 很可能是因为跨域、MIME 类型不匹配,或 PDF 文件路径 404。
- 确保 PDF 文件与 HTML 同源(同协议、同域名、同端口),或服务端返回正确的
Content-Type: application/pdf - 路径推荐用相对路径,比如
./docs/manual.pdf;避免绝对路径或中文路径(URL 编码易出错) - 加
width和height属性,否则 iframe 可能默认只有 150px 高,显示不全
PDF.js 是唯一真正跨浏览器可控的方案
当需要支持旧版 IE、Safari 15.3 及以下、或要求自定义工具栏/缩放/跳页时,pdfjs-dist 是事实标准。它把 PDF 解析为 Canvas 渲染,完全绕过浏览器内置 PDF 查看器。
最简接入方式(CDN + 一行 JS):
<canvas id="pdf-canvas"></canvas><script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@3.4.120/build/pdf.min.js"></script><script>
pdfjsLib.getDocument('./sample.pdf').promise.then(pdf => {
pdf.getPage(1).then(page => {
const canvas = document.getElementById('pdf-canvas');
const ctx = canvas.getContext('2d');
const viewport = page.getViewport({ scale: 1.5 });
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({ canvasContext: ctx, viewport });
});
});
</script>
注意点:
-
pdfjsLib.GlobalWorkerOptions.workerSrc必须显式设置(CDN 地址需与版本一致),否则新版 PDF.js 会报Missing PDF worker - 默认不带 UI,如需翻页/缩放,得自己写 DOM 控件,或直接用官方
viewer.html(但需整套部署) - 首次加载较慢,因要下载 worker 和解析 PDF;可预加载第一页,后续页按需获取
移动端 Safari 和微信内嵌浏览器的特殊处理
iOS Safari 对 <iframe></iframe> 嵌入 PDF 支持不稳定:有时只显示第一屏、不响应滚动、或直接触发下载。微信 WebView(尤其 iOS)更激进,常直接调起系统 PDF 阅读器,脱离页面控制。
实操建议:
- 优先检测用户代理:
navigator.userAgent.includes('MicroMessenger')或/iPhone|iPad/.test(navigator.userAgent) - 对微信或 iOS Safari,改用
@#@#@#@#@#@#@#@#@#@0,并提示“将在新窗口打开” - 若坚持内嵌,PDF.js 是唯一可靠选择,但需确认其 worker 脚本在微信环境下能正常加载(部分企业微信会拦截 CDN)
安全与性能容易被忽略的三个点
PDF 文件不是普通图片,加载和渲染成本高,且存在潜在风险。
- 不要直接允许用户上传 PDF 后前端渲染 —— 恶意 PDF 可能触发 PDF.js 的解析漏洞(如 CVE-2023-30547),必须服务端先做格式校验和沙箱解析
- 大文件(>10MB)会导致内存暴涨甚至页面崩溃;建议前端用
fetch先 HEAD 请求,检查Content-Length,超限时提示“文件过大,请下载查看” - 如果 PDF 来自第三方 URL,务必配置
iframe的sandbox属性(如sandbox="allow-scripts"),禁用弹窗、表单提交等能力
真正麻烦的从来不是“怎么显示”,而是“谁提供 PDF、有多大、从哪来、用户在哪看”。这几个条件一组合,方案就得换三轮。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











