文件魔数十六进制值校验失效:MIME类型验证返回错误提示
问题诊断与修复方案
你遇到的问题核心是条件判断的逻辑错误,导致无论文件头是否正确,都会触发错误提示。让我一步步拆解问题并修复:
1. 核心错误:逻辑运算符使用错误
你的代码里的判断条件:
if(header2 !=='d0cf11e0' || header2 !=='504b34'){
这里用了||(逻辑或),但实际上你需要的是&&(逻辑与)。原因很简单:
- 任何一个文件头值,不可能同时等于
'd0cf11e0'(doc格式魔数)和'504b34',所以不管文件头是什么,这个条件都会返回true,永远触发错误提示。 - 正确的逻辑应该是:当文件头既不是doc的魔数,也不是docx的魔数时,才提示错误。
2. 修正后的完整代码
jQuery(document).ready(function() { jQuery.fn.hasMimetype = function(ctrl) { try { ctrl.value = null; } catch(ex) { } if (ctrl.value) { ctrl.parentNode.replaceChild(ctrl.cloneNode(true), ctrl); } } const fileSelector2 = document.getElementById('file') jQuery('#file').change(function(event) { const file = event.target.files[0] const filereader = new FileReader() filereader.onloadend = function(evt) { var header2 = ""; var arr = (new Uint8Array(evt.target.result)).subarray(0, 4); for(var i = 0; i < arr.length; i++) { // 补零保证两位十六进制,避免比如0x03变成'3'导致匹配失败 header2 += arr[i].toString(16).padStart(2, '0'); } // 修正逻辑运算符为&&,同时修正docx的标准魔数 if(header2 !=='d0cf11e0' && header2 !=='504b0304'){ alert(`检测到文件头:${header2}`); alert("仅支持doc/docx格式文件"); $('#file').hasMimetype(fileSelector2); } } filereader.readAsArrayBuffer(file); }); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <input type="file" id="file" name="file" />
3. 额外优化细节
- 魔数准确性:你之前写的
504b34并不是标准docx的前4字节魔数,docx属于ZIP压缩包格式,标准前4字节魔数是504b0304,我已经在代码里修正了这个点。 - 十六进制补零:添加
padStart(2, '0')确保每个字节的十六进制表示都是两位,避免因为单个字符的十六进制值(比如3而非03)导致匹配失败。 - 代码可读性:建议把
header2、fileSelector2这类带数字的命名改成更语义化的名字,比如fileHeader、fileInput,后续维护会更方便。
内容的提问来源于stack exchange,提问作者sAnS
相关产品推荐
相关产品推荐

