如何让pdf.js在本地file://协议环境下正常运行?
让pdf.js在file://协议下本地运行的可行方案
问题背景
我有一个本地Web应用,需要提取PDF文件中的数据,pdf.js是合适的工具,但它的模块机制在file://协议下会触发跨域请求错误。搭建本地Web服务器能解决CORS问题,但对用户操作过于复杂。此前的旧方案(将模块当作普通JS加载)因语法差异(export成为关键字)已失效;官方文档提到的npx gulp generic-legacy命令实际生成的是.mjs文件而非预期的.js;已知可通过Webpack或Rollup实现需求,但不清楚具体方法。注:用户通过<input>组件上传文件,无需顾虑PDF本地存储问题。
可行方案
方案一:使用UMD预构建文件(最简单)
pdf.js提供了UMD格式的预构建文件,可直接作为普通JS加载,无需模块机制,避免file://下的跨域问题:
- 获取对应版本的UMD文件:下载
pdf.umd.min.js和pdf.worker.umd.min.js(从pdf.js官方发布包中获取) - 将两个文件放入本地项目目录
- 修改HTML代码如下:
<!doctype html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>pdf.js 本地测试</title> <script src="pdf.umd.min.js"></script> </head> <body> <input id="fileUploader" type="file" accept=".pdf"> <p>PDF页数:<span id="pageCount"></span></p> </body> <script> // 配置Worker路径为本地文件 pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.umd.min.js'; document.getElementById('fileUploader').addEventListener('change', ({ target }) => { const reader = new FileReader(); reader.addEventListener('load', async () => { const buffer = reader.result; const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(buffer) }).promise; document.getElementById('pageCount').textContent = pdf.numPages; }); reader.readAsArrayBuffer(target.files[0]); }); </script> </html>
直接用浏览器打开该HTML文件(file://协议)即可正常运行。
方案二:用Rollup打包为IIFE格式(自定义构建)
若需要自定义pdf.js代码,可通过Rollup将其打包为无模块依赖的IIFE格式:
- 获取pdf.js源码,进入源码目录安装依赖:
npm install npm install rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-replace --save-dev
- 创建主文件打包配置
rollup.config.js:
import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; export default { input: 'src/pdf.js', output: { file: 'dist/pdf.bundle.js', format: 'iife', name: 'pdfjsLib', sourcemap: false }, plugins: [ resolve({ browser: true }), commonjs(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), preventAssignment: true }) ] };
- 创建Worker文件打包配置
rollup.config.worker.js:
import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import replace from '@rollup/plugin-replace'; export default { input: 'src/pdf.worker.js', output: { file: 'dist/pdf.worker.bundle.js', format: 'iife', name: 'pdfjsWorker', sourcemap: false }, plugins: [ resolve({ browser: true }), commonjs(), replace({ 'process.env.NODE_ENV': JSON.stringify('production'), preventAssignment: true }) ] };
- 执行打包命令:
npx rollup -c rollup.config.js npx rollup -c rollup.config.worker.js
- 使用打包后的文件,HTML代码参考方案一,将脚本路径替换为
dist/pdf.bundle.js和dist/pdf.worker.bundle.js即可。
内容的提问来源于stack exchange,提问作者Teepeemm
相关产品推荐
相关产品推荐

