如何优化3个输入文件的验证代码 计划使用jQuery实现相关校验功能
现有代码问题梳理
- 存在多处语法错误:包括字段名拼写错误(
docmuent_1应为document_1)、超全局变量调用符号错误($_FILES()应使用方括号$_FILES[])、字符串拼接引号未闭合、逻辑判断括号缺失等,现有代码无法正常运行 - 校验逻辑混乱:3个文件的校验条件逻辑矛盾,没有做文件格式校验,也没有覆盖全所有必填场景,重复冗余代码多
- 存在安全漏洞:直接使用原始上传文件名存储,容易被上传恶意脚本,也没有校验文件真实类型,仅靠后缀判断存在被篡改风险
- 存储路径错误:目标存储路径拼接缺少分隔斜杠,会导致文件存储位置异常
后端优化实现
优化后的PHP代码统一了校验逻辑,增加了格式校验、文件名过滤、错误统一处理逻辑,参考如下:
<?php // 允许上传的后缀 $allowedExt = ['xls', 'xlsx', 'doc', 'docx', 'jpg', 'jpeg', 'png']; // 存储根目录 $uploadRoot = $_SERVER["DOCUMENT_ROOT"] . '/mdh/files/'; // 没有目录先创建 if (!is_dir($uploadRoot)) { mkdir($uploadRoot, 0755, true); } $error = false; $msg = ''; // 循环校验3个文件 for ($i = 1; $i <= 3; $i++) { $field = "document_{$i}"; // 判断文件是否上传 if (!isset($_FILES[$field]) || $_FILES[$field]['error'] != UPLOAD_ERR_OK) { $error = true; $msg = '请上传所有要求的文件'; break; } // 校验后缀 $fileExt = strtolower(pathinfo($_FILES[$field]['name'], PATHINFO_EXTENSION)); if (!in_array($fileExt, $allowedExt)) { $error = true; $msg = '文件格式不正确,仅支持excel、word、jpg、png格式'; break; } // 过滤文件名,避免恶意路径 $fileName = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $_FILES[$field]['name']); // 避免重名覆盖,加时间戳前缀 $saveName = time() . '_' . $fileName; $savePath = $uploadRoot . $saveName; // 移动文件 if (!move_uploaded_file($_FILES[$field]['tmp_name'], $savePath)) { $error = true; $msg = '文件保存失败,请重试'; break; } } if ($error) { echo json_encode([ 'error' => true, 'message' => $msg ]); exit; } // 所有文件上传成功后的后续逻辑 echo json_encode([ 'error' => false, 'message' => '文件上传成功' ]);
前端jQuery校验方案
可以在表单提交前先做前端校验,减少不必要的后端请求,实现逻辑如下:
首先是表单HTML示例:
<form id="uploadForm" enctype="multipart/form-data" method="post"> <input type="file" name="document_1" class="upload-file" accept=".xls,.xlsx,.doc,.docx,.jpg,.jpeg,.png"> <input type="file" name="document_2" class="upload-file" accept=".xls,.xlsx,.doc,.docx,.jpg,.jpeg,.png"> <input type="file" name="document_3" class="upload-file" accept=".xls,.xlsx,.doc,.docx,.jpg,.jpeg,.png"> <button type="submit">提交</button> </form>
对应的jQuery校验代码:
$(function() { const allowedExt = ['xls', 'xlsx', 'doc', 'docx', 'jpg', 'jpeg', 'png']; $('#uploadForm').on('submit', function(e) { let pass = true; // 逐个校验文件 $('.upload-file').each(function() { const file = this.files[0]; // 校验是否选择文件 if (!file) { alert('请上传所有要求的文件'); pass = false; return false; } // 校验后缀 const ext = file.name.split('.').pop().toLowerCase(); if (!allowedExt.includes(ext)) { alert('文件格式不正确,仅支持excel、word、jpg、png格式'); pass = false; return false; } }) // 校验不通过阻止提交 if (!pass) { e.preventDefault(); } }) })
内容的提问来源于stack exchange,提问作者Jose German Perez Sanchez
相关产品推荐
相关产品推荐

