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

前端JavaScript实现PDF上传校验:区分原生PDF与扫描PDF并限制原生PDF上传

用pdfjs.express区分原生PDF与扫描PDF,实现上传限制

嘿,我刚好处理过类似的需求,用pdfjs.express完全能搞定这个扫描PDF/原生PDF的判别!核心思路其实很简单:原生PDF本质是可编辑的数字文档,每页包含大量可提取的文本;而扫描PDF本质是图片集合,即使做了OCR,每页的文本量也远低于原生PDF。我们可以通过提取PDF每页的文本内容,结合阈值判断来实现需求。

下面是完整的实现步骤和代码示例:

1. 基础准备

首先引入pdfjs.express的依赖(可以用CDN或者本地引入),同时准备好文件上传的HTML控件:

<!-- 文件上传控件 -->
<input type="file" id="pdfUpload" accept=".pdf">
<!-- 状态提示区域 -->
<div id="uploadStatus" style="margin-top:10px;"></div>

<!-- 引入pdfjs.express库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfjs-express/8.7.0/pdfjs-express.min.js"></script>

2. 核心判别逻辑

编写JavaScript代码,实现PDF文本提取与判别:

const uploadInput = document.getElementById('pdfUpload');
const statusDiv = document.getElementById('uploadStatus');

// 自定义阈值:每页平均文本长度低于此值则判定为扫描PDF(可根据业务调整)
const SCAN_PDF_TEXT_THRESHOLD = 50;

// 监听文件上传事件
uploadInput.addEventListener('change', async (e) => {
  const selectedFile = e.target.files[0];
  if (!selectedFile) return;

  try {
    statusDiv.textContent = '正在分析PDF文件,请稍等...';
    
    // 初始化PDF文档实例
    const pdfDoc = await PDFNet.PDFDoc.createFromBlob(selectedFile);
    await pdfDoc.initSecurityHandler(); // 处理加密PDF
    
    const totalPages = await pdfDoc.getPageCount();
    let totalTextLength = 0;

    // 遍历每页提取文本
    for (let pageNum = 1; pageNum <= totalPages; pageNum++) {
      const currentPage = await pdfDoc.getPage(pageNum);
      const textExtractor = await PDFNet.TextExtractor.create();
      await textExtractor.begin(currentPage);
      
      // 获取当前页的纯文本内容(去除空白字符后统计)
      const pageText = await textExtractor.getText();
      totalTextLength += pageText.trim().length;
    }

    // 计算每页平均文本长度
    const avgTextPerPage = totalTextLength / totalPages;
    
    // 判定并给出结果
    if (avgTextPerPage < SCAN_PDF_TEXT_THRESHOLD) {
      statusDiv.textContent = '✅ 扫描PDF验证通过,可继续上传!';
      // 这里添加你的上传逻辑,比如将selectedFile发送到后端
    } else {
      statusDiv.textContent = '❌ 禁止上传原生PDF,请选择扫描类型的PDF文件!';
      uploadInput.value = ''; // 清空上传控件
    }

  } catch (error) {
    statusDiv.textContent = '⚠️ PDF分析失败,请检查文件是否损坏或格式正确!';
    console.error('处理出错:', error);
    uploadInput.value = '';
  }
});

// 初始化PDFNet(替换为你的pdfjs.express许可证密钥)
// 开发阶段可以申请免费试用密钥,正式环境需购买授权
PDFNet.initialize('YOUR_TRIAL_OR_LICENSE_KEY');

3. 关键注意事项

  • 许可证密钥:pdfjs.express需要许可证才能解锁全部功能,开发时可以去官网申请免费试用密钥,正式上线记得换成付费授权。
  • 阈值调整:SCAN_PDF_TEXT_THRESHOLD可以根据你的业务场景微调。比如如果允许OCR后的扫描PDF,可适当提高阈值(比如100);如果要严格区分纯扫描无OCR的PDF,可降低阈值(比如20)。
  • 性能优化:对于页数极多的PDF,没必要遍历所有页面,可以只检查前3-5页的平均文本长度,大幅提升处理速度。
  • 特殊情况处理:极少数原生PDF可能是纯图片(比如将原生文档导出为图片再合成PDF),这种会被误判为扫描PDF,但这种场景非常罕见,一般无需额外处理。

内容的提问来源于stack exchange,提问作者stackismylifedontyouforget

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 21:37:35