使用jQuery ajax实现PHP文件上传时后端提示文件为空怎么解决?
基于jQuery Ajax实现PHP文件上传时后端始终返回文件为空的问题修复
我在开发基于Ajax的PHP文件上传功能,移除jQuery Ajax逻辑后上传功能可正常运行,说明问题不出在后端。我查找了相关资料多次调整代码后,后端仍然始终返回文件为空的报错,以下是我的代码和最终修复方案:
前端代码
<input class="input is-link" id="file" name="file" type="file"> <button id="sendImg" class="button">Send</button> </form>
初始jQuery代码
$(function(){ $("#chatsCard").on('click', '#sendImg', function (e){ e.preventDefault(); //alert("test"); var filedata = $("#file").prop("files")[0]; var recipient = $("#uname").html(); //alert(filedata); $.ajax({ type:'post', url:'upload.php', contentType:false, processData:false, cache:false, dataType:'json', data:{ //rec:recipient, filedata }, success:function(data){ alert (data); } });//ajax end });//click end });//doc end
后端PHP代码
<?php session_start(); require("assets/db.php"); $logged = $_SESSION['logged']; //始终触发该报错 if(empty($_FILES['file'])){ $response = "No picture selected"; echo json_encode($response); exit; } $imgFolder = "media/"; $fileTpath = $_FILES['file']['tmp_name']; $fileSize = filesize($fileTpath); $info = finfo_open(FILEINFO_MIME_TYPE); $filetype = finfo_file($info, $fileTpath); $filetype = explode ("/",$filetype); $filetype = $filetype[1]; $allowedFiles = array("jpg" , "png" , "jpeg"); //重命名文件 $newName = uniqid(8); $newName = "recipient". $newName. "." . $filetype; //校验文件大小 if($fileSize > 21464568){ $response = "Picture is greater than 2MB, Resize and try again"; echo json_encode($response); exit; } //校验文件格式 elseif(!in_array($filetype, $allowedFiles)){ $response= "You are only allowed to upload jpeg,jpg or png"; echo json_encode($response); exit; } //校验文件是否存在 elseif(file_exists($imgFolder.$newName)){ $response = "Failed!!! Upload again!!!"; echo json_encode($response); exit; } //移动文件到目录 else{ move_uploaded_file($fileTpath,$imgFolder .$newName); $recipient = $_POST['rec']; $time = date("d-M-y")." at ". date("h:ia"); $msg = "media"; //写入消息表 $q = "INSERT INTO messaging(message,sender, receiver,time) VALUES(?,?,?,?)"; $stm = $conn->prepare ($q); $stm->bind_param("ssss",$msg,$logged,$recipient,$time); $stm->execute(); //写入媒体资源表 $q1 = "INSERT INTO media(sender,mediaName,mediaType) VALUES(?,?,?)"; $stm = $conn->prepare ($q1); $stm->bind_param("sss",$logged,$newName,$fileType); $stm->execute(); //返回成功响应 $response = "success"; echo json_encode($response); exit; } ?>
已尝试的无效调整方案
- 第一次调整
var fd = new FormData(); var file = $("#file").props('files')[0]; var filedata = fd.append("file",filedata);
调整后仍然返回“未选择图片”的报错
- 第二次调整
var fd = new FormData($("#mediaPic")[0])
将fd作为data参数传入ajax请求,仍然返回相同报错。
问题原因&修复代码
错误点汇总
- 初始ajax请求直接把文件对象放到普通对象中传输,没有用FormData封装,浏览器不会按照
multipart/form-data格式处理文件数据,后端无法识别到$_FILES参数 - 第一次调整的语法错误:jQuery获取文件属性的方法是
prop()不是props(),多写了字母s;同时fd.append()没有返回值,不需要赋值给变量,代码中变量定义混乱 - 第二次调整的前提错误:用表单实例初始化FormData需要保证对应id为
mediaPic的form标签真实存在,且文件输入框在该form内部,否则无法读取到文件参数
修复后的jQuery代码
$(function(){ $("#chatsCard").on('click', '#sendImg', function (e){ e.preventDefault(); var fd = new FormData(); // 正确读取文件对象 var filedata = $("#file").prop("files")[0]; var recipient = $("#uname").html(); // 把文件和额外参数都加入FormData fd.append('file', filedata); fd.append('rec', recipient); $.ajax({ type:'post', url:'upload.php', contentType: false, processData: false, cache: false, dataType: 'json', // 直接传入FormData实例 data: fd, success:function(data){ alert(data); } }); }); });
如果要使用表单初始化FormData的方案,需要先修正前端表单结构:
<form id="mediaPic" method="post" enctype="multipart/form-data"> <input class="input is-link" id="file" name="file" type="file"> <button id="sendImg" class="button">Send</button> </form>
对应jQuery代码可以简化为:
var fd = new FormData($("#mediaPic")[0]); fd.append('rec', $("#uname").html());
内容的提问来源于stack exchange,提问作者Mayor Abel
相关产品推荐
相关产品推荐

