You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

纯浏览器端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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:28:12