PDF.js 未加载 PDF 的首要原因是 pdf.worker.js 路径错误或 404,需确保通过 PDFJS.GlobalWorkerOptions.workerSrc 显式指定其相对于 HTML 页面的正确路径,并验证该 URL 可直接在浏览器访问。

PDF.js 查看器没加载出 PDF?先确认 pdf.worker.js 路径是否正确
PDF.js 渲染 PDF 依赖主库 pdf.min.js 和独立的 Web Worker 脚本 pdf.worker.js。常见错误是只引入了前者,或 pdf.worker.js 路径 404 —— 浏览器控制台会明确报错:Failed to load PDF worker script 或 Cannot find module 'pdfjs-dist/build/pdf.worker.entry'。
实操建议:
- 从 官方 GitHub releases 页面 下载完整 dist 包(如
pdfjs-3.4.120-dist.zip),解压后将整个build/目录放入项目静态资源路径(例如./static/pdfjs/) - 在 HTML 中显式指定 worker 路径,放在
pdf.min.js加载之后、任何 PDF 渲染逻辑之前:
PDFJS.GlobalWorkerOptions.workerSrc = './static/pdfjs/build/pdf.worker.min.js';
注意:路径必须相对于当前 HTML 页面 URL,不是相对于 JS 文件位置;开发服务器(如 Vite、Webpack Dev Server)若启用了静态资源别名,需确保该路径能被直接访问到(可手动在浏览器打开验证)。
用 PDFViewerApplication 还是手写 PDFDocumentLoadingTask?看你的集成深度
PDF.js 提供两套 API:高层封装的 PDFViewerApplication(即默认查看器 UI)和底层渲染 API(PDFDocumentLoadingTask + PDFPageProxy)。多数场景下,直接复用官方 viewer 更快,但前提是接受它的 DOM 结构和样式。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- 若只需嵌入一个带缩放、翻页、搜索的完整查看器,直接用
web/viewer.html并 iframe 嵌入最省事(但跨域限制、样式隔离强) - 若要深度定制 UI(比如仅显示单页、与 React/Vue 组件融合、自定义工具栏),必须走底层 API,绕过
PDFViewerApplication - 不要混用:比如在已初始化
PDFViewerApplication的页面里再调用getDocument(),容易触发 canvas 冲突或重复加载
简单底层加载示例(无 UI):
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
const loadingTask = pdfjsLib.getDocument('./sample.pdf');<br>loadingTask.promise.then(pdf => {<br> return pdf.getPage(1);<br>).then(page => {<br> const viewport = page.getViewport({ scale: 1.5 });<br> const canvas = document.getElementById('pdf-canvas');<br> const context = canvas.getContext('2d');<br> canvas.height = viewport.height;<br> canvas.width = viewport.width;<br> page.render({ canvasContext: context, viewport }).promise;<br>});
canvas 渲染模糊或文字失真?检查 devicePixelRatio 和 viewport 缩放
PDF.js 默认按 CSS 像素渲染 canvas,但高 DPI 屏幕(MacBook、Windows 缩放 125%/150%)下会出现文字发虚、线条锯齿——本质是 canvas 的 backing store 像素数没跟上设备像素比。
实操建议:
- 创建 canvas 时主动适配
window.devicePixelRatio:
const ratio = window.devicePixelRatio || 1;<br>canvas.style.width = `${viewport.width / ratio}px`;<br>canvas.style.height = `${viewport.height / ratio}px`;<br>canvas.width = viewport.width * ratio;<br>canvas.height = viewport.height * ratio;- 渲染前重置 canvas context 缩放,避免字体模糊:
context.scale(ratio, ratio);
漏掉这两步,即使 PDF 源文件是矢量,输出到屏幕也会降质。尤其在 Electron 或桌面 PWA 场景中,这个细节极易被忽略。
PDF 跨域加载失败(CORS error)?服务端响应头比前端 hack 更可靠
直接用 getDocument('https://example.com/doc.pdf') 加载外域 PDF 会触发 CORS 报错:Blocked by CORS policy: No 'Access-Control-Allow-Origin' header。有人试图用代理、fetch + blob URL、甚至禁用浏览器安全策略来绕,但都不可靠或不适用于生产。
实操建议:
- 让 PDF 所在服务端返回正确的响应头:
Access-Control-Allow-Origin: *(或具体域名),并确保Access-Control-Allow-Methods: GET存在 - 如果无法改服务端(如第三方公开 PDF),用同域代理中转(Nginx、Vercel Edge Function、Cloudflare Worker),把请求变成同源
- 避免用
fetch先拉取再传 blob —— PDF.js 内部仍会尝试发起新请求,且失去 range 请求支持(影响大文件加载速度)
PDF.js 本身支持 withCredentials,但前提是服务端明确允许,否则连预检请求(OPTIONS)都会失败。
PDF.js 集成真正的难点不在“能不能显示”,而在“能不能稳定、清晰、合规地显示”。worker 路径、canvas 像素比、CORS 头这三处,任何一个出问题,用户看到的就是白屏、模糊字、或控制台一长串红色报错 —— 它们不常出现在入门教程里,但线上环境十有八九卡在这儿。


















