使用Javascript FormData、AJAX $.post和PHP上传文件时遇非法调用错误
解决jQuery $.post使用FormData时的"Uncaught TypeError: Illegal invocation"错误
这个问题我之前也碰到过,其实是jQuery的$.post方法的特性导致的——咱们一步步来拆解解决:
错误原因
$.post是jQuery封装的简化POST请求方法,它默认会把传入的数据做URL编码序列化处理。但FormData是专门用于文件上传的二进制数据容器,jQuery尝试去序列化它的时候,会触发"Illegal invocation"错误,因为FormData的内部方法不允许被这种方式调用。
另外你的PHP代码还有个小语法错误,后面我会一起修正。
解决方案
改用完整的$.ajax方法,并且必须设置两个关键参数:
processData: false:告诉jQuery不要自动处理请求数据,FormData已经是符合上传要求的格式了contentType: false:让浏览器自动生成正确的multipart/form-data请求头(包含自动生成的boundary分隔符),手动设置这个值会丢失boundary,导致后端无法解析文件
修正后的JavaScript代码
$("#input_file").change(function(e){ $("#label_small_input_file").html(e.target.files[0].name); }); $("#form_image_upload").submit(function(e){ e.preventDefault(); let fd = new FormData(this); $.ajax({ url: "PHP/PHP_SIMPLE_AJAX_IMAGE.php", type: "POST", data: fd, processData: false, contentType: false, success: function(data){ $("#Sub_Div_7").html(data); } }); });
修正后的PHP代码
原代码里if(isset($_FILES['input_file_n'])少了闭合括号,同时建议添加文件未上传时的默认值,避免undefined报错:
<?PHP if(isset($_FILES['input_file_n'])) { $F_name = $_FILES['input_file_n']['name']; $F_tmpnm = $_FILES['input_file_n']['tmp_name']; $F_type = $_FILES['input_file_n']['type']; $F_size = $_FILES['input_file_n']['size']; } else { // 文件未上传时的默认值 $F_name = "No file uploaded"; $F_tmpnm = ""; $F_type = ""; $F_size = 0; } $text_1 = isset($_POST['simp_text_n']) ? $_POST['simp_text_n'] : "NULL"; echo "Filename: " . $F_name . " Tempname: " . $F_tmpnm . " Type: ".$F_type . " Size: " . $F_size . " TextInput: " . $text_1 ; ?>
补充说明
如果不设置contentType: false,jQuery会默认使用application/x-www-form-urlencoded请求头,这和文件上传需要的multipart/form-data完全不兼容,后端就无法识别到上传的文件。而processData: false是防止jQuery把FormData转换成字符串,破坏原有的二进制数据结构。
内容的提问来源于stack exchange,提问作者Madventures
相关产品推荐
相关产品推荐

