React Native通过Laravel API上传文件时出现Axios网络错误
问题描述
仅在向FormData中添加图片时出现网络错误,登录、获取条目等其他API调用均正常。
React Native 端代码
const newItem = async () => { const formData = new FormData(); const headers = new Headers(); headers.append('Content-Type','multipart/form-data'); const imageData = { type: 'image/jpeg', uri: image.assets[0].uri, name: 'upload.jpg' } formData.append('image', imageData); formData.append('user_id', userInfo.data.id); formData.append('title', title); formData.append('description', desc); formData.append('price', price); formData.append('bid_start', bidStart); formData.append('bid_end', bidEnd); formData.append('winning_bid', price); // console.log(imageData) try { const res = await axios.post(`${BASE_URL}/items`,formData); const data = await res.json(); console.log(data) } catch(error) { console.log(error) } };
调试器返回的错误响应
{ "message": "Network Error", "name": "AxiosError", "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": { "FormData": null }, "headers": { "Accept": "application/json, text/plain, */*", "Content-Type": "application/x-www-form-urlencoded" }, "method": "post", "url": "http://10.0.2.2:8000/api/items", "data": { "_parts": [ [ "image", { "type": "image/jpeg", "uri": "file:///data/user/0/com.waste_mobile/cache/rn_image_picker_lib_temp_acebc359-4515-4d0e-aa20-aa3fefdaa63f.jpg", "name": "upload.jpg" } ], [ "user_id", 3 ], [ "title", "asdasd" ], [ "description", "asdaasd" ], [ "price", "50" ], [ "bid_start", "2022-10-17T16:20:24.412Z" ], [ "bid_end", "2022-10-17T16:20:24.412Z" ], [ "winning_bid", "50" ] ] } }, "code": "ERR_NETWORK", "status": null }
Laravel 后端 Item 控制器代码
public function store(Request $request) { $validator = Validator::make($request->all(),[ 'user_id'=>'required', 'image'=>'required|image|mimes:jpeg,png,jpg,gif|max:2048', 'title'=>'required', 'description'=>'required', 'price'=>'required', 'bid_start'=>'required', 'bid_end'=>'required|after:bid_start' ]); $response = array('message'=>'','data'=>'','success'=>false); if($validator->fails()) { $response['message'] = $validator->errors(); return Response::json($response); } $request['winning_bid'] = $request['price']; $image = ""; if($request->hasFile('image')) { $file = $request->file('image'); $extention = $file->getClientOriginalExtension(); $filename = time().'.'.$extention; $file->move('uploads/items/', $filename); $image = $filename; } //manual add image name //do not alter code below $item = Item::create(array_merge($request->all(),['image'=>$image])); $response['message'] = "Item successfully added."; $response['data'] = $item; $response['success'] = true; return Response::json($response); }
问题分析与修复方案
从错误响应可见,请求的Content-Type被自动设为application/x-www-form-urlencoded,但你手动添加了multipart/form-data头——这是核心问题:Axios处理FormData时会自动生成带boundary的正确Content-Type,手动设置反而会破坏格式,触发网络错误。
修复步骤
删除手动设置的Content-Type头
移除代码中headers.append('Content-Type','multipart/form-data');这一行,让Axios自动处理请求头。适配Android端文件URI
React Native中Android的文件URI需要去掉file://前缀,否则后端无法正确识别:import { Platform } from 'react-native'; const imageData = { type: 'image/jpeg', uri: Platform.OS === 'android' ? image.assets[0].uri.replace('file://', '') : image.assets[0].uri, name: 'upload.jpg' }正确传入请求头配置
确保将headers传入Axios请求参数中:const res = await axios.post(`${BASE_URL}/items`, formData, { headers });
修复后的完整代码
import { Platform } from 'react-native'; const newItem = async () => { const formData = new FormData(); const headers = new Headers(); const imageData = { type: 'image/jpeg', uri: Platform.OS === 'android' ? image.assets[0].uri.replace('file://', '') : image.assets[0].uri, name: 'upload.jpg' } formData.append('image', imageData); formData.append('user_id', userInfo.data.id); formData.append('title', title); formData.append('description', desc); formData.append('price', price); formData.append('bid_start', bidStart); formData.append('bid_end', bidEnd); formData.append('winning_bid', price); try { const res = await axios.post(`${BASE_URL}/items`, formData, { headers }); const data = res.data; // Axios自动解析JSON,无需调用res.json() console.log(data) } catch(error) { console.log(error) } };
后端验证(可选)
在Laravel控制器开头添加日志,确认是否接收到文件:
\Log::info('Request received', $request->all()); \Log::info('Has image file: ', ['status' => $request->hasFile('image')]);
查看storage/logs/laravel.log即可验证文件接收状态。
内容的提问来源于stack exchange,提问作者mixyespitlick
相关产品推荐
相关产品推荐

