浏览器中使用 pdf-inspector - WebAssembly 教程
API 参考WebAssembly
pdf-inspector 可以编译成 WebAssembly 在浏览器里跑——这是它最特别的一点:解析完全发生在用户的浏览器本地,文件永远不出设备。本站首页的在线 Demo 就是这么实现的。
安装
npm install @firecrawl/pdf-inspector-wasm纯前端项目也能用,不需要任何后端。
核心 API
import init, { processPdf, detectPdf, classifyPdf, extractText } from '@firecrawl/pdf-inspector-wasm'
// 1. 初始化 wasm(应用启动时做一次即可)
await init()
const bytes = new Uint8Array(await file.arrayBuffer())
// 2. 一步到位:分类 + Markdown
const result = processPdf(bytes)
console.log(result.pdfType) // "TextBased" | "Scanned" | "Mixed" | "ImageBased"
console.log(result.markdown)
// 3. 只判定类型,不提取
const info = detectPdf(bytes)
// 4. 轻量分类(与原生 Node API 同构)
console.log(classifyPdf(bytes).pagesNeedingOcr)传选项控制行为:
const result = processPdf(bytes, {
pages: [1, 3, 5], // 只处理部分页
profile: 'compact', // 省 token 的紧凑输出
includePageMarkers: true, // 加分页标记
})完整的拖入即解析示例
<input type="file" id="pdf" accept=".pdf,application/pdf" />
<pre id="out"></pre>import init, { processPdf } from '@firecrawl/pdf-inspector-wasm'
await init()
document.getElementById('pdf').addEventListener('change', async (e) => {
const file = e.target.files[0]
if (!file) return
const bytes = new Uint8Array(await file.arrayBuffer())
try {
const result = processPdf(bytes)
document.getElementById('out').textContent =
`[${result.pdfType}]\n${result.markdown}`
}
catch (err) {
document.getElementById('out').textContent = `解析失败:${err}`
}
})隐私卖点:为什么文件不出设备
- 解析逻辑是编译进 wasm 的 Rust 代码,在浏览器沙箱里运行
- 没有上传请求、没有后端转发,
file.arrayBuffer()读完就留在内存里 - 非常适合敏感文件(合同、财报、病历)的在线解析场景
浏览器端行为要点
- 单线程构建:不需要 COOP/COEP 跨域隔离头,任何静态托管都能跑
- CJK 开箱即用:CMap 已内嵌,中日韩字体解码不依赖文件系统
- 同步执行:
init()之后提取是同步的;大文档放 Web Worker 里调用,避免卡住 UI - 无 OCR:纯图片型 PDF 需要另外接 OCR 步骤——WASM 端会给出明确的类型判定和提示,而不是假装成功
性能与体积
- wasm 二进制约几 MB(gzip 后更小),首次加载会有一点延迟,之后常驻;懒加载
import可以把内核从首屏挪走 - 解析速度和原生接近——同样的 Rust 内核,只是跑在 wasm 沙箱里
- 本站首页的在线 Demo 就是它实现的:拖 PDF 即出类型判定和 Markdown
小提示
await init()只做一次,把实例存起来复用,别每次解析都重新初始化- Vite 项目建议把包加入
optimizeDeps.exclude,避免 wasm asset 被 dev 预构建处理异常(本站就是这么配的) - 大文件(几百页)在浏览器里要留意内存,wasm 会占用与文件等量的内存