React Native Android端Multipart FormData接口调用失败求助
问题:Android端无法发起Multipart FormData POST请求,iOS正常
接口信息
- POST接口地址:
http://100.20.168.179/public/index.php/maintenances/create_ticket - 请求体示例:
const SelectData = { "description": "Fff", "room_id": "Ghh", "maintenance_unique_id": "1662630778728", "lang_flag": "en", "asset_type": "2", "longitude": "0.0", "work_type": "69", "user_id": "20", "latitude": "0.0", "area": "291", "location": "22", "urgency_level": "4", "category_name": "", "device_id": "2", "captured_adress": "3377", "reported_on": "2022-09-08 03:22:58", "is_mediafile": "0" }
前端FormData构造代码
const form = new FormData(); const imageFileData = { name: imageFilePath?.fileName, type: `image/jpg`, uri: imageFilePath?.uri, }; form.append('webdata', JSON.stringify(SelectData)); if (imageFilePath?.uri || videoFilePath?.uri ) { form.append('file_name', imageFileData ); } else { form.append('file_name', JSON.stringify(null)); } addTicket(Config.BASE_URL + '/maintenances/create_ticket',form);
useAddTicket.ts代码
const useAddTicket = () => { // const [data, setData] = useState(); const [isLoading, setIsLoading] = useState(false); const navigation = useNavigation(); const addTicket = async (url: string, data: any) => { console.log('formDatain Hook', data); console.log('url Hook', url); console.log('internet', globals.GlobalVariable.isConnected); if (globals.GlobalVariable.isConnected === true) { try { setIsLoading(true); const headers = { 'Content-Type': 'multipart/form-data; boundary=V2ymHFg03ehbqgZCaKO6jy', // Connection: 'keep-alive', // 'Content-Disposition': 'form-data; name="webdata"', }; const response = await axios.post(url, data, { headers: headers }); if (response.data.sStatus == 1) { setIsLoading(false) console.log('useAddTicket Data res -->', response); Alert.alert(`${response.data.sData.maintenance_id}`, response.data.sMessage, [ { text: 'OK', onPress: () => navigation.goBack() }, ]); } } catch (error) { console.log('useAddTicket error -->', error); setIsLoading(false); } } else { Alert.alert('No Internet!'); } }; return { isLoading, // data, addTicket, }; }; export default useAddTicket;
问题现象
代码在iOS模拟器中可正常运行,但在Android模拟器及真机中均无法发起接口调用,始终处于加载状态。日志显示网络连接正常,但请求未到达端点。
解决方案
1. 移除手动设置的Content-Type头
Axios处理FormData时会自动生成正确的multipart/form-data头和对应的boundary,手动指定固定boundary会导致Android端解析异常。修改addTicket函数的headers配置:
// 原代码 const headers = { 'Content-Type': 'multipart/form-data; boundary=V2ymHFg03ehbqgZCaKO6jy', }; // 修改后 const headers = {}; // 或直接省略headers参数,让Axios自动处理
2. 修正Android端文件URI格式
Android中FormData接收的文件URI需要调整格式,原生content://开头的URI需转换为file://格式:
import { Platform } from 'react-native'; const imageFileData = { name: imageFilePath?.fileName, type: `image/jpg`, uri: Platform.OS === 'android' ? `file://${imageFilePath?.uri}` : imageFilePath?.uri, };
3. 避免向FormData中添加JSON格式的null
无文件时,直接不添加file_name字段,或传入空值而非JSON字符串的null:
// 原代码 else{ form.append('file_name', JSON.stringify(null)); } // 修改后 else{ // 可选:不添加该字段,或传入空字符串 // form.append('file_name', ''); }
4. 检查Android网络配置
- 确保
AndroidManifest.xml添加网络权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 若接口为HTTP协议,需在
application标签中开启明文流量:
<application ... android:usesCleartextTraffic="true">
验证步骤
- 应用上述修改后重新构建Android项目
- 在Android模拟器/真机中测试接口调用,确认请求是否到达后端
- 查看控制台日志,若仍有问题根据新错误信息进一步排查
内容的提问来源于stack exchange,提问作者Harshal Kalavadiya
相关产品推荐
相关产品推荐

