前端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
相关产品推荐
相关产品推荐

