You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React Native 0.6图片上传服务器遇网络请求失败等问题求助

解决React Native 0.6图片上传"Network Request failed"及返回数据异常问题

我看你在React Native 0.6 + Genymotion环境下遇到了图片上传的一系列棘手问题:fetch报"Network Request failed",RNFetchBlob响应慢到离谱,Axios返回200状态但拿不到有效数据。结合你给出的代码,我整理了几个核心问题和对应的修复方案:

一、先搞定Genymotion的网络连通性

Genymotion模拟器的网络配置是这类问题的高发区,先排查这个基础问题:

  • 先在模拟器自带的浏览器里访问你的服务器地址http://web001.XXX.com:8000,如果打不开,说明模拟器和服务器之间的网络通路有问题:
    • 把Genymotion的网络模式切换为桥接模式(在VirtualBox的虚拟机设置里修改),让模拟器和你的电脑处于同一网段
    • 如果服务器是本地搭建的,别用localhost127.0.0.1,换成你电脑的局域网IP(比如192.168.x.x)——因为模拟器的localhost指向它自己,不是你的电脑
  • 同时确认服务器没有设置IP白名单,拒绝了模拟器的请求

二、修正FormData的构造错误

你的代码里UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.avatarSource , name:'file.jpeg'})有明显的错误:

  • this.state.avatarSource是一个{uri: response.uri}的对象,你应该直接传response.uri或者this.state.avatarSource.uri,而不是整个对象
  • Android和iOS的uri格式不一样,iOS是file://开头,Android可能是content://或直接文件路径,需要统一处理

修正后的Send方法:

import { Platform } from 'react-native';

Send = async () => { 
  let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/"; 
  let UplodedFile = new FormData(); 
  // 处理不同平台的uri格式
  const fileUri = Platform.OS === 'android' 
    ? this.state.avatarSource.uri 
    : this.state.avatarSource.uri.replace('file://', '');
  
  UplodedFile.append('file', {
    type: 'image/jpeg', 
    uri: fileUri, 
    name: 'file.jpeg'
  }); 
  // 不要手动设置Content-Type,让fetch自动生成带boundary的multipart/form-data头
  fetch(url, { 
    method: 'POST', 
    body: UplodedFile,
    headers: {
      // 如果服务器需要认证,在这里加Authorization头,比如:
      // 'Authorization': 'Bearer your-token-here'
    }
  }) 
  .then(response => {
    // 先检查响应状态再转JSON
    if (!response.ok) {
      throw new Error(`请求失败!状态码:${response.status}`);
    }
    return response.json();
  })
  .then(response => { 
    console.log("上传成功!"); 
    console.log("返回数据:", response); 
  }) 
  .catch(error => { 
    console.error("上传出错:", error); 
  }); 
}

三、检查权限配置

别漏掉必要的系统权限,否则也会导致上传失败:

  • Android端:在android/app/src/main/AndroidManifest.xml里添加权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • iOS端:在ios/项目名/Info.plist里添加相册访问权限说明:
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择上传的图片</string>

四、解决Axios返回200但空数据的问题

用Axios时同样要注意FormData的构造,另外可以开启调试模式查看请求细节:

import axios from 'axios';
import { Platform } from 'react-native';

Send = async () => {
  const url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
  const formData = new FormData();
  const fileUri = Platform.OS === 'android' 
    ? this.state.avatarSource.uri 
    : this.state.avatarSource.uri.replace('file://', '');
  
  formData.append('file', {
    uri: fileUri,
    name: 'file.jpeg',
    type: 'image/jpeg'
  });

  try {
    const response = await axios.post(url, formData, {
      // 让Axios自动处理multipart/form-data的boundary,不要手动设置Content-Type
      headers: {
        // 这里加其他必要的头信息,比如认证
      },
      // 开启调试,接收所有状态码的响应
      validateStatus: (status) => true
    });
    console.log("响应状态码:", response.status);
    console.log("响应数据:", response.data);
  } catch (error) {
    console.error("Axios请求错误:", error);
  }
}

五、优化RNFetchBlob的响应速度

RNFetchBlob慢大概率也是网络问题,你可以设置超时时间并确认网络配置:

import RNFetchBlob from 'rn-fetch-blob';

Send = async () => {
  const url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
  const formData = new FormData();
  const fileUri = this.state.avatarSource.uri;
  
  formData.append('file', {
    uri: fileUri,
    name: 'file.jpeg',
    type: 'image/jpeg'
  });

  RNFetchBlob.fetch('POST', url, {
    // 让RNFetchBlob自动处理multipart/form-data
  }, formData)
  .setTimeout(30000) // 设置30秒超时,避免无限等待
  .then(res => {
    console.log("RNFetchBlob响应:", res.json());
  })
  .catch(err => {
    console.error("RNFetchBlob错误:", err);
  });
}

建议先从网络连通性和FormData构造这两个最常见的问题入手,应该能解决你的"Network Request failed"和返回空数据的问题。

内容的提问来源于stack exchange,提问作者Omar Trigui

火山引擎 最新活动