实现表单拼接线上文本计算SHA256并校验前导双零的脚本无运行结果排查
代码问题逐点定位
- 表单事件语法+默认行为问题:原代码
<form onsubmit= check()>没给属性值加引号,极易触发解析错误;且表单提交默认会触发整页刷新,当前JS运行上下文会被直接清空,逻辑根本执行不完。 - 异步读取的作用域+时序问题:
read函数里的blockchain是定义在XHR回调内的局部变量,外层的check函数根本无法访问;且XHR是异步请求,原代码在调用read后完全没等文件读取完成,就直接执行拼接逻辑,此时根本拿不到txt里的内容。 - 用户输入获取逻辑完全失效:原代码
document.getElementById("try") = new string(input)是无效写法——既没有调用value属性取出输入框内的用户文本,input变量本身从未定义,且JS中字符串构造器是大写的String,小写string是类型标识,不能当构造函数用。 - DOM赋值逻辑错误:通过
getElementById拿到的是DOM节点对象,不能直接用等号给节点赋字符串值,必须操作节点的textContent/innerHTML属性才能修改页面显示内容。 - 哈希校验逻辑写反:原代码
hash.substring(2)=='00'的逻辑是从哈希字符串的第3个字符开始截取整段后缀,拿几十位的长字符串和两位的'00'做等值比较,永远不会成立。要判断哈希以两个0开头,需要截取前两位做匹配,或者直接用startsWith方法判断。 - 异步函数的返回值处理错误:
sha256是async异步函数,调用后返回的是Promise对象,原代码直接拿这个Promise值做拼接、做前缀判断,根本拿不到真实的哈希字符串结果。
修正后可运行的完整代码
<form id="answerForm"> <label for="try">Write your answer.</label><br> <input type="text" id="try" name="try"><br> <input type="submit" value="Send"> </form> <p id="return"></p> <script> // 封装XHR读取为Promise,方便异步等待 function read(textFile){ return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', textFile); xhr.onload = () => resolve(xhr.response); xhr.onerror = () => reject(new Error('文件读取失败')); xhr.send(); }) } async function check(e){ // 阻止表单默认的页面刷新行为 e.preventDefault(); try { // 等待txt文件读取完成 const blockchain = await read('blockchain.txt'); // 正确获取输入框的用户值,去掉前后多余空格 const input = document.getElementById("try").value.trim(); // 拼接内容 const whole = blockchain + input; // 等待哈希计算完成 const hash = await sha256(whole); // 正确校验是否以00开头 if(hash.startsWith('00')){ document.getElementById("return").textContent = "congratulations!"; } else { document.getElementById("return").textContent = "Try again."; } } catch (err) { document.getElementById("return").textContent = "运行出错:" + err.message; } } // 给表单绑定提交事件,替代原来的内联onsubmit写法 document.getElementById('answerForm').addEventListener('submit', check); async function sha256(message) { const msgBuffer = new TextEncoder('utf-8').encode(message); const hashBuffer = await window.crypto.subtle.digest('SHA-256', msgBuffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join(''); return hashHex; } </script>
运行注意事项
- 不要直接双击打开HTML文件运行,要把HTML文件和
blockchain.txt放在同一个静态Web服务的路径下访问,否则浏览器会因为本地文件跨域限制,拦截XHR的txt读取请求。 window.crypto.subtle仅在HTTPS环境或者localhost本地服务下可用,直接用file协议打开时这个API会不存在,会触发哈希计算错误。- 可以先在控制台打印拼接后的
whole内容和算出的hashHex值,确认读取到的txt内容、拼接顺序、哈希值都符合预期后,再做前缀校验逻辑。
内容的提问来源于stack exchange,提问作者aciddioxide
相关产品推荐
相关产品推荐

