使用FileReader读取修改后文件不触发onload回调的解决方案问询
问题解决方案
根因说明
浏览器中input[type=file]选中文件后,返回的File对象是选中时刻的文件状态快照,当外部修改磁盘上的原文件后,该缓存的文件句柄会直接失效,此时调用FileReader读取旧句柄就会出现无响应、不触发onload回调的问题。
解决方案
方案1:重置文件选择逻辑(全浏览器兼容)
该方案无需特殊API适配,兼容所有新旧浏览器,只需要调整原有交互逻辑,每次点击校验按钮时清空原有的文件缓存,强制读取最新的文件内容:
function loadFile() { const fileInput = document.getElementById("fileinput"); const output = document.getElementById("validation_output"); output.innerHTML = ""; // 清空已有文件缓存,强制读取最新文件 if (fileInput.value) { fileInput.value = ""; output.textContent = "请重新选择要校验的文件"; // 主动触发文件选择弹窗 fileInput.click(); // 监听文件选择完成事件后再执行读取 fileInput.onchange = function() { if (!fileInput.files[0]) return; const reader = new FileReader(); reader.onload = receivedText; reader.readAsArrayBuffer(fileInput.files[0]); } return; } // 首次选择文件的原有逻辑 const reader = new FileReader(); reader.onload = receivedText; reader.readAsArrayBuffer(fileInput.files[0]); }
方案2:使用File System Access API(现代浏览器适用,体验最优)
如果用户使用Chrome、Edge等现代浏览器,可以使用该API实现一次授权、多次无感读取最新文件内容,无需每次校验都重新选择文件:
首先修改HTML中按钮的触发逻辑:
<input type="button" value="Validate File" onclick="triggerValidate()">
再调整JS代码:
// 全局存储文件访问句柄 let fileHandle = null; async function triggerValidate() { const output = document.getElementById("validation_output"); output.innerHTML = ""; // 首次校验需要用户授权选择文件 if (!fileHandle) { [fileHandle] = await window.showOpenFilePicker({ types: [{ description: 'JSON文件', accept: {'application/json': ['.json']} }] }); } // 每次都通过句柄读取磁盘上的最新文件内容 const latestFile = await fileHandle.getFile(); const reader = new FileReader(); reader.onload = receivedText; reader.readAsArrayBuffer(latestFile); } function receivedText(e) { document.getElementById("validation_output").textContent = "Successfully read from file!"; }
内容的提问来源于stack exchange,提问作者user3553031
相关产品推荐
相关产品推荐

