Angular12+Laravel8上传Logo报getClientOriginalExtension空对象错误如何解决
问题根因
- 浏览器出于安全限制,直接读取file表单控件的值只会返回
C:\fakepath\文件名格式的虚拟路径,并非真实的文件对象 - 原提交逻辑使用
application/json格式传输数据,该格式无法传输二进制文件内容,导致Laravel端$request->file('company_logo')无法获取到有效文件,返回null后调用方法就触发了报错
修复步骤
1. 调整Angular前端代码
1.1 组件类修改
首先新增变量存储选中的真实文件对象,提交时改用FormData包装所有请求参数:
export class SignupCompanyComponent implements OnInit { isLinear = true; isLoading = false; companySetupForm!: FormGroup; companyForm!: FormGroup; idForm!: FormGroup; imageSrcLogo!: string | ArrayBuffer; selectedLogoFile: File | null = null; // 新增变量存储选中的logo文件 onFileChange(event: any) { const reader = new FileReader(); if(event.target.files && event.target.files.length) { const [file] = event.target.files; this.selectedLogoFile = file; // 存储真实文件对象 reader.readAsDataURL(file); reader.onload = () => { this.imageSrcLogo = reader.result as string; this.companyForm.patchValue({ company_logo: file.name // 表单存储文件名用于校验 }); }; } } // ...原有其他代码保持不变 onSubmit() { this.isSubmitted = true; if(this.companyForm.invalid || this.idForm.invalid) { return; } const formCompanyData = this.companyForm.getRawValue(); const formIdData = this.idForm.getRawValue(); // 改用FormData包装请求参数,支持文件传输 const formData = new FormData(); formData.append('companyName', formCompanyData.companyName); formData.append('registrationNumber', formIdData.registrationNumber); // 追加logo文件 if(this.selectedLogoFile) { formData.append('company_logo', this.selectedLogoFile, this.selectedLogoFile.name); } this.spinnerService.show(); this.isLoading = true; // 不要手动设置Content-Type,浏览器会自动生成带boundary的正确请求头 return this.api.post('companies/company/signup', formData) .pipe(first()) .subscribe( data => { this.tokenHandler(data); }); } }
1.2 模板代码无需修改,原有绑定逻辑可正常使用
2. 调整Laravel后端代码
优化文件判断逻辑,避免空对象调用方法:
public function register(StoreCompanySetupRequest $request) { $arr_company = [ 'name' => $request->companyName, 'registration_number' => $request->registrationNumber, ]; // 改用hasFile方法判断是否存在有效上传文件 if ($request->hasFile('company_logo') && $request->file('company_logo')->isValid()) { $company_logo = $request->file('company_logo'); $new_name = rand() . '.' . $company_logo->getClientOriginalExtension(); // 自动创建存储目录避免目录不存在报错 $savePath = public_path('storage/images/company_logo'); if(!file_exists($savePath)) { mkdir($savePath, 0755, true); } $company_logo->move($savePath, $new_name); $arr_company['company_logo'] = $new_name; } $newCompany = Company::create($arr_company); return response()->json(['code' => 200, 'msg' => '创建成功', 'data' => $newCompany]); }
同时请确认StoreCompanySetupRequest表单验证类中已添加文件规则:
public function rules() { return [ 'companyName' => 'required|string|min:3|max:100', 'registrationNumber' => 'required|string|max:100', 'company_logo' => 'nullable|file|mimes:jpg,jpeg,bmp,png,gif,svg|max:2048', ]; }
额外注意事项
- 请确认已执行
php artisan storage:link创建存储软链接,否则前端无法访问上传后的Logo文件 - 请确保
public/storage/images/company_logo目录有web服务用户的写入权限
内容的提问来源于stack exchange,提问作者midowu
相关产品推荐
相关产品推荐

