还在通过文件名做防重吗

30 阅读1分钟

前端防重的两种方式。

  1. 比较文件名及大小是否相同。

  2. 通过文件内容(哈希值)检查,通过计算文件的哈希值来检测重复文件。

好多同学是通过第一种方式来比较文件是否相同的。这里来说说第二种方式。

如何计算文件的哈希值?

 async function hashFile(file) {
 	// 获取文件的二进制数据 
    const arrayBuffer = await file.arrayBuffer();
    // 计算SHA-256哈希值
    const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
    // 将哈希值转换为字节数组
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    // 将字节数组转换为十六进制字符串
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
 }

Demo

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>File Upload Prevent Duplicate</title>
</head>
<body>
  <input type="file" id="fileInput" multiple>
  <button onclick="uploadFiles()">Upload</button>
  <ul id="fileList"></ul>

  <script>
    const uploadedFiles = new Set();

    async function hashFile(file) {
      const arrayBuffer = await file.arrayBuffer();
      const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer);
      const hashArray = Array.from(new Uint8Array(hashBuffer));
      const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
      return hashHex;
    }

    async function uploadFiles() {
      const fileInput = document.getElementById('fileInput');
      const fileList = document.getElementById('fileList');
      const files = Array.from(fileInput.files);

      for (const file of files) {
        const fileHash = await hashFile(file);

        if (!uploadedFiles.has(fileHash)) {
          uploadedFiles.add(fileHash);

          const listItem = document.createElement('li');
          listItem.textContent = `${file.name} (${file.size} bytes)`;
          fileList.appendChild(listItem);
        } else {
          alert(`File "${file.name}" is already uploaded.`);
        }
      }

      // 清空文件输入框
      fileInput.value = '';
    }
  </script>
</body>
</html>

在这里插入图片描述