Laravel中用AJAX上传图片获取base64报Illegal invocation错如何解决
报错原因
Uncaught TypeError: Illegal invocation错误由两个核心问题导致:
- 你将FormData对象作为普通参数嵌套进了AJAX的data对象中,jQuery默认会对请求数据执行序列化操作,FormData对象无法被默认序列化,直接抛出该错误
- 使用FormData上传文件时,缺少
processData: false和contentType: false两个必要配置,没有告知jQuery不对数据做额外处理
解决方案
方案1:FormData传文件,后端转base64(推荐,传输效率更高)
调整AJAX代码
所有请求参数都统一追加到FormData对象中,同时添加必要配置:
$(document).on('click', '.store_new_item', function () { var item_name = $('.item_name').val(); var formData = new FormData(); // 所有参数统一追加到FormData formData.append('item_name', item_name); formData.append('item_image', $('.item_image')[0].files[0]); $.ajax({ url: '{{ url('/item/add-new-item') }}', type: "POST", headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }, data: formData, // 必须添加以下两行配置 processData: false, contentType: false, success: function(res) { // 自定义成功逻辑 } }); });
调整Laravel控制器代码
上传的文件需要用file()方法获取,不能用get():
// 校验文件是否合法上传 if ($request->hasFile('item_image') && $request->file('item_image')->isValid()) { $file = $request->file('item_image'); // 读取文件内容转base64 $item_image = base64_encode(file_get_contents($file->getRealPath())); // 后续业务逻辑 }
方案2:前端提前转base64再上传
如果需要前端先处理图片(预览、裁剪等),可以直接在前端转成base64字符串后上传,不需要使用FormData:
$(document).on('click', '.store_new_item', function () { var item_name = $('.item_name').val(); var file = $('.item_image')[0].files[0]; var reader = new FileReader(); reader.onload = function(e) { // 获取图片base64字符串 var base64Image = e.target.result; $.ajax({ url: '{{ url('/item/add-new-item') }}', type: "POST", headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }, data: { item_name: item_name, item_image: base64Image }, success: function(res) { // 自定义成功逻辑 } }); } reader.readAsDataURL(file); });
控制器直接读取参数即可,若不需要base64前缀可以自行去除:
$item_image = $request->input('item_image'); // 可选:去除base64前缀(data:image/png;base64, 这类标识) $item_image = preg_replace('#^data:image/\w+;base64,#i', '', $item_image);
内容的提问来源于stack exchange,提问作者kashfiq
相关产品推荐
相关产品推荐

