You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery文件上传前MIME类型校验:解决修改扩展名后误判及异常上传问题

问题根因
  • jQuery File Upload插件重复初始化:仅首次校验通过时才初始化上传组件,一旦初始化完成,组件会持续监听文件选择框的change事件,后续校验不通过时,已绑定的上传逻辑仍会自动执行,和前端校验逻辑完全独立。
  • 校验时序错位:FileReader读取文件是异步操作,校验逻辑执行时机晚于上传组件的默认触发时机,往往校验失败提示弹出时,文件已经上传完成。
  • 校验规则不匹配:魔数校验仅覆盖png/gif/jpeg/pdf四种类型,但上传组件的acceptFileTypes规则还允许doc、docx、xls等格式,这类文件没有魔数校验,修改后缀即可绕过。
修复方案
  • 提前初始化上传组件:页面加载完成后直接初始化jQuery File Upload,关闭自动上传(autoUpload设为false),无需放在change事件中按需初始化。
  • 校验逻辑嵌入上传流程:将魔数校验逻辑放到上传组件的add回调中,校验通过后手动调用data.submit()触发上传,校验不通过直接终止流程。
  • 补充完整魔数校验规则:将acceptFileTypes中允许的所有文件格式对应的魔数补充到校验逻辑中,避免后缀篡改绕过。
  • 避免事件重复绑定:初始化上传组件前先解绑旧的change事件,防止逻辑重复执行。
修正后代码示例
'use strict';
// 页面加载完成后直接初始化上传组件
$(function() {
  // 先解绑旧事件避免重复触发
  $('#myfiles').off('change').fileupload({
    downloadTemplateId: 'template-download-gallery',
    uploadTemplateId: 'template-upload-gallery',
    paramName: 'files[]',
    url: 'mydrive-upload.php',
    dataType: 'json',
    autoUpload: false, // 关闭自动上传,校验通过再手动触发
    maxNumberOfFiles: 10,
    acceptFileTypes: /(\.|\/)(pdf|doc|docx|xls|ppt|zip|gif|jpe?g|png)$/i,
    add: function(e, data) {
      var file = data.files[0];
      var fileReader = new FileReader();
      fileReader.onloadend = function (e) {
        var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
        var header = '';
        for (var i = 0; i < arr.length; i++) {
            header += arr[i].toString(16);
        }
        var type = 'unknown';
        switch (header) {
          case '89504e47':
            type = 'image/png';
            break;
          case '47494638':
            type = 'image/gif';
            break;
          case 'ffd8ffe0':
          case 'ffd8ffe1':
          case 'ffd8ffe2':
          case 'ffd8ffe3':
          case 'ffd8ffe8':
            type = 'image/jpeg';
            break;
          case '25504446':
            type = 'application/pdf';
            break;
          // 补充其他允许格式的魔数,例如doc、docx、zip等
          case '504b0304':
            // zip、docx、xlsx、pptx都用这个头,可根据需要进一步校验
            type = 'archive/office';
            break;
          case 'd0cf11e0':
            // doc、xls、ppt等旧版office文件头
            type = 'old-office';
            break;
        }
        // 按需求调整允许的type范围
        if (type === 'unknown') {
          alert("File Type Not Allowed");
          return false;
        } else {
          // 校验通过,触发上传
          data.submit();
        }
      };
      fileReader.readAsArrayBuffer(file);
    }
  });
});
额外注意

前端校验只能做第一层拦截,服务端必须同时做魔数校验和格式校验,避免恶意请求绕过前端直接上传非法文件。

内容的提问来源于stack exchange,提问作者Roger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:06:01