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

如何用JavaScript(Next.js)检测上传的PDF文件是否损坏?

验证损坏PDF的实现方案

基础校验:检查文件标准标识

PDF有固定的格式标识,先通过这个做初步过滤:

  • 检查文件扩展名是否为.pdf(作为基础拦截,避免非PDF文件)
  • 读取文件的前5字节,确认是%PDF-(PDF标准文件头);读取文件末尾10字节,确认包含%%EOF(PDF标准文件尾)

深度校验:用专业库解析验证

基础校验可能漏过那些标识完整但内容损坏的PDF,这时候用pdfjs-dist(Mozilla官方的PDF解析库)尝试加载文件,解析失败则判定为损坏。

步骤1:安装依赖

npm install pdfjs-dist

步骤2:在Next.js客户端组件中实现逻辑

文件上传操作需在客户端完成,所以组件要加上'use client'指令:

'use client';

import { useState } from 'react';
import * as pdfjsLib from 'pdfjs-dist';
import 'pdfjs-dist/build/pdf.worker.min';

export default function PDFUploader() {
  const [error, setError] = useState('');

  const handleFileChange = async (e) => {
    setError('');
    const file = e.target.files[0];
    if (!file) return;

    // 校验扩展名
    if (!file.name.toLowerCase().endsWith('.pdf')) {
      setError('请上传PDF格式文件');
      return;
    }

    const reader = new FileReader();
    reader.onload = async (event) => {
      const arrayBuffer = event.target.result;
      const uint8Array = new Uint8Array(arrayBuffer);
      
      // 校验文件头
      const header = new TextDecoder().decode(uint8Array.slice(0, 5));
      if (header !== '%PDF-') {
        setError('文件不是有效的PDF');
        return;
      }

      // 校验文件尾(允许末尾有换行等空白字符)
      const footer = new TextDecoder().decode(uint8Array.slice(-10));
      if (!footer.includes('%%EOF')) {
        setError('文件不是有效的PDF');
        return;
      }

      // 深度解析校验
      try {
        const pdfDoc = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
        // 额外校验:确保至少有1个有效页面
        if (pdfDoc.numPages < 1) {
          setError('损坏的PDF:无有效页面');
          return;
        }
        // 校验通过,可执行后续上传逻辑
        console.log('PDF验证通过');
      } catch (err) {
        setError('损坏的PDF:无法解析内容');
      }
    };
    reader.readAsArrayBuffer(file);
  };

  return (
    <div>
      <input type="file" accept=".pdf" onChange={handleFileChange} />
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}

注意事项

  • 如果遇到worker加载失败问题,可手动指定worker地址:
    pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.min.js`;
    
  • 针对大文件,可优化头/尾读取逻辑,避免加载整个文件到内存。

内容的提问来源于stack exchange,提问作者Rômulo Valentim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:35:24