如何清理FileReader缓冲区?React文件上传SHA256哈希异常排查
解决文件上传时SHA256哈希值累积错误的问题
你遇到的问题根源其实很直观——你在组件外部创建了一个全局的hash实例,每次调用hash.update()时,这个实例会持续累积传入的缓冲区数据,而不是每次处理新文件时从头开始计算。所以第一个文件的哈希是正确的,但第二个文件的哈希其实是「第一个文件内容+第二个文件内容」的组合哈希,第三次选one.txt时,又是前两次的内容叠加新的one.txt内容的哈希,结果自然就错了。
下面是具体的修复方案,我会把关键改动点和完整代码都列出来:
核心修复思路
每次处理新文件时,都创建一个全新的crypto.Hash实例,而不是复用全局的那个。同时优化一下异步逻辑,避免依赖setState的异步更新导致的潜在问题。
修正后的完整代码
import React, { Component } from "react"; const crypto = require("crypto"); class SearchPage extends Component { constructor(props) { super(props); this.state = { hashOutput: "", fileName: "", // 初始化fileName字段 files: null, }; } onChange(e) { const selectedFile = e.target.files[0]; if (!selectedFile) return; // 增加空值判断,避免取消选择文件时出错 // 直接更新文件名,不用依赖后续state this.setState({ fileName: selectedFile.name }); const reader = new FileReader(); reader.onload = (loadEvent) => { // 关键:每次处理文件时创建全新的哈希实例 const hash = crypto.createHash("sha256"); hash.update(Buffer.from(loadEvent.target.result)); const hashOutput = hash.digest("hex"); this.setState({ hashOutput }); console.log(hashOutput); }; // 直接读取选中的文件,跳过异步的state更新环节 reader.readAsArrayBuffer(selectedFile); } render() { return ( <div> <input type="file" name="file" onChange={(e) => this.onChange(e)} /> {/* 增加UI展示,方便验证结果 */} {this.state.fileName && <p>当前选择文件: {this.state.fileName}</p>} {this.state.hashOutput && <p>SHA256哈希值: {this.state.hashOutput}</p>} </div> ); } } export default SearchPage;
关键改动说明
- 移除全局哈希实例:把
crypto.createHash("sha256")移到reader.onload回调内部,确保每处理一个文件都用全新的哈希对象,不会累积之前的数据。 - 避免依赖异步state:原来的代码里先
setState再通过this.state.files获取文件,但setState是异步的,可能导致读取到旧数据。现在直接使用e.target.files[0]获取当前选中的文件,逻辑更可靠。 - 增加空值判断:防止用户打开文件选择框后取消选择,导致
selectedFile为null的报错情况。 - 补充UI反馈:增加了文件名和哈希值的展示,方便你直观验证结果是否正确。
现在你再依次选择one.txt、two.txt、one.txt,应该都会返回各自正确的SHA256哈希值了。
内容的提问来源于stack exchange,提问作者Hanley Soilsmith
相关产品推荐
相关产品推荐

