如何使用jQuery Ajax将图片上传至服务器?附现有实现代码
jQuery Ajax 图片上传问题排查与正确实现
现有代码存在的问题
- 未阻止表单默认提交行为:绑定submit事件后没有拦截默认逻辑,点击提交按钮会直接触发表单原生跳转,Ajax请求会被直接中断
- Ajax缺少核心配置:使用
FormData传输二进制文件时,jQuery默认会对数据做URL编码、自动设置错误的Content-Type请求头,会导致后端无法正常解析到上传的文件 - 缺少前置校验逻辑:没有判断用户是否选中文件就直接读取
files[0],用户空点提交会直接抛出JS错误
前端修正后代码
HTML部分:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form id="uploadFile"> <input type="file" id="file" accept="image/*" /> <button type="submit">提交上传</button> </form>
JS逻辑:
$(function(){ $('#uploadFile').submit(function(e){ // 阻止表单默认跳转 e.preventDefault(); const fileInput = $('#file')[0]; // 校验是否选中文件 if(!fileInput.files || fileInput.files.length === 0){ alert('请先选择要上传的图片'); return; } const selectFile = fileInput.files[0]; // 校验文件类型是否为图片 if(!selectFile.type.startsWith('image/')){ alert('请选择图片格式文件'); return; } const formData = new FormData(); formData.append('file', selectFile); $.ajax({ url: 'upload.php', type: 'POST', data: formData, // 禁止jQuery对FormData做序列化处理 processData: false, // 禁止jQuery自动设置Content-Type,让浏览器自动生成带正确边界标识的multipart/form-data头 contentType: false, success: function(res) { console.log('服务端返回:', res); alert('上传成功'); }, error: function(xhr) { console.error('请求异常:', xhr); alert('上传失败,请重试'); } }); }); });
后端upload.php 最简参考实现
<?php if($_SERVER['REQUEST_METHOD'] !== 'POST'){ exit('仅支持POST请求'); } // 校验上传文件是否存在、是否无错 if(!isset($_FILES['file']) || $_FILES['file']['error'] !== UPLOAD_ERR_OK){ exit('上传出错,错误码:'.$_FILES['file']['error']); } $uploadFile = $_FILES['file']; // 校验文件后缀 $allowExt = ['jpg','jpeg','png','gif','webp']; $fileExt = strtolower(pathinfo($uploadFile['name'], PATHINFO_EXTENSION)); if(!in_array($fileExt, $allowExt)){ exit('仅允许上传jpg/png/gif/webp格式的图片'); } // 提前创建upload目录并设置写入权限 $savePath = './upload/'.uniqid().'.'.$fileExt; if(move_uploaded_file($uploadFile['tmp_name'], $savePath)){ exit('上传成功,文件访问路径:'.$savePath); }else{ exit('文件保存失败,请检查upload目录权限'); } ?>
注意事项
- 存储上传文件的目录需要提前创建,并且给PHP运行进程分配写入权限,否则会出现文件保存失败的问题
processData: false和contentType: false两个配置是jQuery上传文件的必填项,缺失任意一个都会导致后端拿不到文件数据- 如果需要展示上传进度,可以在ajax配置中增加xhr字段,绑定progress事件即可实现
内容的提问来源于stack exchange,提问作者Mohammad Sajid Choudhary
相关产品推荐
相关产品推荐

