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

如何在上传至网页前检测文件是否来自Zip压缩包?

解决方案:检测拖拽文件是否为压缩包内未解压的损坏文件

浏览器的拖拽API出于安全限制,不会暴露文件的来源路径或是否来自压缩包这类信息,所以没法直接从dataTransfer里拿到标记。但可以通过**验证文件的实际内容(魔数/文件签名)**来判断文件是否有效,间接识别出从压缩包拖拽出的未解压损坏文件。

核心思路

从压缩包内拖拽出的文件,浏览器实际获取到的是该文件在压缩包中的原始压缩数据流,而非解压后的正常文件内容。这类文件的开头字节(魔数)会和对应格式的正常文件不符,我们可以通过读取文件头部的几个字节来验证。

TypeScript 实现示例

1. 读取文件头部字节的工具函数

// 读取文件前N个字节,用于验证魔数
async function getFileHeader(file: File, byteCount: number): Promise<Uint8Array> {
  const fileSlice = file.slice(0, byteCount);
  const buffer = await fileSlice.arrayBuffer();
  return new Uint8Array(buffer);
}

2. 针对不同文件类型的验证逻辑

这里以常见的PNG、JPG、文本文件为例:

async function isValidUploadFile(file: File): Promise<boolean> {
  // 验证PNG文件:魔数为 0x89 0x50 0x4E 0x47
  if (file.type === 'image/png') {
    const header = await getFileHeader(file, 4);
    return header[0] === 0x89 && header[1] === 0x50 && header[2] === 0x4E && header[3] === 0x47;
  }

  // 验证JPG文件:魔数为 0xFF 0xD8 0xFF
  if (file.type === 'image/jpeg') {
    const header = await getFileHeader(file, 3);
    return header[0] === 0xFF && header[1] === 0xD8 && header[2] === 0xFF;
  }

  // 验证文本文件:尝试读取部分内容,判断是否为乱码(压缩后的二进制数据转字符串会是乱码)
  if (file.type.startsWith('text/')) {
    const textSlice = await file.slice(0, 100).text();
    // 简单判断是否包含大量不可打印字符
    const unprintableCharRatio = (textSlice.match(/[\x00-\x1F\x7F-\xFF]/g)?.length || 0) / textSlice.length;
    return unprintableCharRatio < 0.2;
  }

  // 其他文件类型可参考对应格式的魔数自行扩展
  return true;
}

3. 在drop事件中使用验证逻辑

const dropArea = document.getElementById('upload-area') as HTMLDivElement;

dropArea.addEventListener('drop', async (e) => {
  e.preventDefault();
  const files = Array.from(e.dataTransfer.files);

  for (const file of files) {
    const isFileValid = await isValidUploadFile(file);
    if (!isFileValid) {
      alert(`文件「${file.name}」可能来自未解压的压缩包,请先解压后再上传`);
      continue;
    }
    // 执行正常的上传流程
    await uploadFile(file);
  }
});

// 示例上传函数
async function uploadFile(file: File) {
  // 你的上传逻辑代码
}

补充说明

  • 魔数是每种文件类型的固定标识,几乎所有标准文件格式都有对应的魔数(比如PDF的魔数是%PDF-,Zip包本身的魔数是PK\x03\x04),可以根据你支持的上传文件类型逐一扩展验证逻辑。
  • 对于没有明确魔数的自定义格式,可以尝试读取文件内容并尝试解析,若解析失败则判定为无效文件。
  • 这种方法无法100%覆盖所有场景,但能解决绝大多数从压缩包拖拽未解压文件的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:50:38