使用jQuery $.post发送FormData报Illegal Invocation错误原因分析
问题
使用jQuery的简写$.post方法发送包含文件上传的FormData进行AJAX请求时,遇到了“Illegal Invocation”错误,但使用完整的$.ajax方法时该错误消失。后端采用CodeIgniter框架。
表单代码
<form id="add_category_form" action="<?= base_url("CategoriesController/process_add_category") ?>" method="post" enctype="multipart/form-data"> <input type="hidden" name="<?= $this->security->get_csrf_token_name() ?>" value="<?= $this->security->get_csrf_hash() ?>" /> <h2>Add a Category</h2> <ul> <li> <input type="text" name="name" required> <label>Category Name</label> </li> <li> <textarea name="description" required></textarea> <label>Description</label> </li> <label>Upload Images (5 Max)</label> <input type="file" name="image" id="category_image" accept="image/*"> </ul> <!-- FIXME: center the content of this last li tag --> <button type="button" data-dismiss="modal" aria-label="Close">Cancel</button> <button type="submit">Save</button> </form>
使用$.post的代码
$(document).ready(function() { $("#add_category_form").submit(function(e) { e.preventDefault(); let url = $(this).attr("action"); if ($("#category_image").val() == "") { alert("Please add an image"); } else { let formData = new FormData(this); // Pass the form element $.post(url, formData, function(response) { console.log(response); csrfName = response.csrfName; $("input[name='<?= $this->security->get_csrf_token_name() ?>']").val(response.newCsrfToken); }, "json"); } return false; });
使用$.ajax的代码
$(document).ready(function() { $("#add_category_form").submit(function(e) { e.preventDefault(); if ($("#category_image").val() == "") { alert("Please add an image"); } let formData = new FormData(this); $.ajax({ url: "<?= base_url(''); ?>CategoriesController/process_add_category", type: "POST", data: formData, processData: false, contentType: false, dataType: "json", success: function(response) { console.log(response); csrfName = response.csrfName; $("input[name='<?= $this->security->get_csrf_token_name() ?>']").val(response.newCsrfToken); }, error: function(xhr, status, error) { console.error("AJAX Error:", status, error); } }); return false; }); });
原因分析与解答
为啥$.post会报“Illegal Invocation”错误?
$.post是$.ajax的简化版,它默认做了两个不适合文件上传的操作:
- 自动把请求头的
contentType设为application/x-www-form-urlencoded,这是普通文本表单的格式,不支持二进制文件传输。 - 自动开启
processData: true,会把传入的数据转成URL编码的字符串。但FormData是专门存储文件的二进制容器,jQuery强行序列化它时,会触发浏览器安全限制,抛出“Illegal Invocation”错误。
为啥$.ajax能正常运行?
你在$.ajax的配置里手动设置了两个关键参数:
processData: false:告诉jQuery不要对FormData进行序列化处理,直接传递原始对象。contentType: false:让浏览器自动生成适合FormData的请求头(multipart/form-data,这才是文件上传的正确格式)。
这两个参数是文件上传AJAX请求的必备配置,但$.post这类简写方法没有提供直接设置的入口,无法满足FormData的传输要求。
非要用$.post行不行?
可以,但需要改成带配置对象的写法,本质和$.ajax无差异:
$.post({ url: url, data: formData, processData: false, contentType: false, dataType: "json", success: function(response) { console.log(response); csrfName = response.csrfName; $("input[name='<?= $this->security->get_csrf_token_name() ?>']").val(response.newCsrfToken); } });
不过这种写法反而不如直接用$.ajax清晰,更推荐使用完整的$.ajax配置。
内容的提问来源于stack exchange,提问作者Adrian Gaile Singh
相关产品推荐
相关产品推荐

