Laravel 6中AJAX上传PDF文件报错,求正确文件传递方法
Laravel 6 AJAX上传PDF文件及表单值解决方案
报错原因
「Call to a member function getClientOriginalExtension() on null」这个错误,是因为你用$('.my_doc').val()拿到的只是文件的本地路径字符串,根本没把实际的文件流传给后端,所以$request->file('my_doc')返回null,调用方法自然报错。AJAX上传文件必须用FormData对象封装文件和表单数据,还要配置对应的AJAX参数。
修正后的Blade视图JS代码
把原来的AJAX请求改成用FormData处理:
$(document).on('click', '.store_new', function () { // 创建FormData对象来封装数据 let formData = new FormData(); // 添加文本输入值 formData.append('phone', $('.phone').val()); // 添加文件对象,注意要取files[0]获取实际文件 formData.append('my_doc', $('#my_doc')[0].files[0]); // 加入CSRF令牌 formData.append('_token', '{{ csrf_token() }}'); $.ajax({ url: '{{ url('/admin/add-new-item') }}', type: "POST", data: formData, // 关键配置:禁止自动处理数据、不要设置Content-Type,让浏览器自动生成正确的请求头 processData: false, contentType: false, success: function (response) { // 这里可以加成功提示逻辑,比如弹窗提示 console.log('上传完成'); }, error: function (jqXHR, textStatus, errorThrown) { // 处理上传失败的情况 console.error('上传出错:', errorThrown); } }); });
修正后的控制器代码
建议加上数据验证,避免非法请求,同时处理目录不存在的情况:
use Illuminate\Http\Request; use Illuminate\Support\Facades\File; public function store(Request $request) { // 验证输入合法性:手机号必填、文件必须是PDF且不超过2MB $request->validate([ 'phone' => 'required|string', 'my_doc' => 'required|file|mimes:pdf|max:2048', ]); $file = $request->file('my_doc'); // 用时间戳生成唯一文件名,比rand()更不容易重复 $new_name = time() . '.' . $file->getClientOriginalExtension(); $storageDir = public_path('final_doc'); // 确保存储目录存在,不存在则创建 if (!File::exists($storageDir)) { File::makeDirectory($storageDir, 0755, true); } // 移动文件到目标目录 $file->move($storageDir, $new_name); // 返回成功响应给前端 return response()->json(['status' => 'success', 'msg' => '文件上传成功']); }
核心注意事项
- 必须用
FormData封装文件,不能直接传文件路径字符串 - AJAX必须设置
processData: false和contentType: false,否则jQuery会破坏文件数据的格式 - 控制器先做验证,避免因为无文件或非法文件导致报错
- 确保
final_doc目录有服务器写入权限,否则文件无法保存
内容的提问来源于stack exchange,提问作者Esfak
相关产品推荐
相关产品推荐

