纯浏览器端JavaScript解锁已知密码的PDF文档可行方案问询
浏览器端解密受密码保护PDF的可行方案
Good question! 这个需求在浏览器环境完全可以实现,你遇到的pdf-lib问题是因为它本身不支持处理需要密码解密的内容加密PDF——它的ignoreEncryption参数仅针对权限限制类加密(比如禁止打印、复制),没法处理需要密码才能打开的PDF。下面给你推荐两个靠谱的纯前端实现方案:
1. 首选方案:Mozilla官方PDF.js(pdfjs-dist)
PDF.js是目前浏览器端最成熟的PDF处理库,原生支持密码解密,还能完整保留原PDF的格式和内容。
实现思路
用PDF.js加载加密PDF并解密,再结合pdf-lib把解密后的页面复制到新文档,最后导出无加密版本。
示例代码
async function decryptAndDownloadPDF(pdfFile, password) { // 先读取本地文件为Uint8Array const fileReader = new FileReader(); const pdfBytes = await new Promise((resolve) => { fileReader.onload = (e) => resolve(new Uint8Array(e.target.result)); fileReader.readAsArrayBuffer(pdfFile); }); // 加载PDF.js核心库和Worker(可通过CDN引入) const pdfjsLib = window['pdfjs-dist/build/pdf']; pdfjsLib.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.js'; try { // 解密加载PDF const pdfDoc = await pdfjsLib.getDocument({ data: pdfBytes, password: password }).promise; // 用pdf-lib创建新的无加密PDF const { PDFDocument } = await import('pdf-lib'); const newPdf = await PDFDocument.create(); // 逐页复制解密后的页面 for (let pageNum = 0; pageNum < pdfDoc.numPages; pageNum++) { // pdf-lib的copyPages直接接收PDF.js解密后的文档实例 const [copiedPage] = await newPdf.copyPages(pdfDoc, [pageNum]); newPdf.addPage(copiedPage); } // 导出并下载 const decryptedPdfBytes = await newPdf.save(); const blob = new Blob([decryptedPdfBytes], { type: 'application/pdf' }); const downloadUrl = URL.createObjectURL(blob); const aTag = document.createElement('a'); aTag.href = downloadUrl; aTag.download = 'decrypted-document.pdf'; aTag.click(); URL.revokeObjectURL(downloadUrl); } catch (err) { console.error('处理失败:', err); alert(err.message.includes('Incorrect password') ? '密码错误' : 'PDF处理失败,请检查文件'); } } // 使用示例:绑定到文件上传按钮 document.getElementById('pdf-upload').addEventListener('change', (e) => { const password = prompt('请输入PDF密码:'); if (password && e.target.files[0]) { decryptAndDownloadPDF(e.target.files[0], password); } });
注意事项
- 需通过CDN或npm同时引入
pdfjs-dist和pdf-lib,建议使用最新稳定版保证兼容性 - 区分用户密码和所有者密码:PDF.js只需要用户密码(打开PDF的密码)就能解密内容,所有者密码用于修改权限,无需传入
- 跨域问题:如果加载远程PDF,需要服务器配置CORS允许访问;本地文件则无此限制
2. 替代方案:pdf-parse(适合简单需求)
如果你的PDF内容格式简单,不需要保留复杂排版,可以用pdf-parse先解密提取文本和页面信息,再用pdf-lib重新生成PDF。不过这种方式可能会丢失部分格式细节,不如PDF.js方案完整。
为什么pdf-lib无法满足需求?
pdf-lib的官方文档明确说明:它不支持解密受密码保护的PDF,仅能处理权限限制类加密(比如禁止打印),所以你遇到的Input document is encrypted异常是预期行为,ignoreEncryption参数也确实无法绕过内容加密。
内容的提问来源于stack exchange,提问作者Sariful
相关产品推荐
相关产品推荐

