当我使用react-native init (RN版本0.29.1)创建一个全新的项目,并在渲染方法中获取公共facebook演示电影API时,它抛出了一个网络请求失败。有一个非常无用的堆栈跟踪,我不能调试网络请求在chrome控制台。这是我发送的fetch:

fetch('http://facebook.github.io/react-native/movies.json')
      .then((response) => response.json())
      .then((responseJson) => {
        return responseJson.movies;
      })
      .catch((error) => {
        console.error(error);
      });

当前回答

我在Android 9上也遇到了同样的问题,因为“http”,问题通过添加Android:usesCleartextTraffic=“true”来解决 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"/>
<application
  android:usesCleartextTraffic="true"
 .......>
 .......
</application>

其他回答

如果你在REST api中使用docker,我的一个工作案例是将主机名:http://demo.test/api替换为机器ip地址:http://x.x.x.x/api。你可以通过检查你的无线网络的ipv4来获取IP。你的手机也应该有wifi。

问题可能出在服务器配置上。

Android 7.0有一个bug。Vicky Chijwani提出的解决方案:

配置您的服务器以使用椭圆曲线prime256v1。为 例如,在Nginx 1.10中,你可以通过设置ssl_ecdh_curve来实现 prime256v1;

修复TypeError:在Android调试版本中将文件上传到http而不是https时网络请求失败

在react-native 0.63.2(我正在测试)或更高版本中,如果只是使用fetch将文件上传到http(而不是https)服务器,将会遇到TypeError:网络请求失败。

在这里,我使用axios@0.27.2作为运行在Android手机上的客户端,成功地将文件上传到react-native-file-server作为运行在另一台Android手机上的服务器。

客户端需要编辑JAVA和JS代码,服务器不需要编辑JAVA代码。

在调试构建中,必须注释掉这个文件android/app/src/debug/java/com/YOUR_PACKAGE_NAME/ReactNativeFlipper.java中的43行

38      NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
39      NetworkingModule.setCustomClientBuilder(
40          new NetworkingModule.CustomClientBuilder() {
41            @Override
42            public void apply(OkHttpClient.Builder builder) {
43      //        builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
44            }
45          });
46      client.addPlugin(networkFlipperPlugin);

也许还需要添加android:usesCleartextTraffic="true"下的<应用程序的android/app/src/main/AndroidManifest.xml,在我的测试,这是不必要的调试和发布构建。

  onFileSelected = async (file) => {
    // API ref to the server side BE code `addWebServerFilter("/api/uploadtodir", new WebServerFilter()`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L356
    // could not be 'localhost' but IP address
    const serverUploadApi = 'http://192.168.1.123:8080/api/uploadtodir';

    // the folder on server where file will be uploaded to, could be e.g. '/storage/emulated/0/Download'
    const serverFolder = '/storage/emulated/0/FileServerUpload';

    const fileToUpload = {
      // if want to upload and rename, it can be `name: 'foo.bar'`, but can not be 'foo'
      // only if your server upload code support file name without type, on our server
      // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L372
      // will cause java.lang.StringIndexOutOfBoundsException in substring()
      name: file.name,

      // type is necessary in Android, it can be 'image/jpeg' or 'foo/bar', but can not be
      // 'foo', 'foo/', '/foo' or undefined, otherwise will cause `[AxiosError: Network Error]`
      type: 'a/b',

      uri: Platform.OS === 'android' ? file.uri : file.uri.replace('file://', ''),
    };

    const form = new FormData();
    form.append('path', serverFolder);
    form.append('uploadfile', fileToUpload);

    // ref to the server side FE code `this.axios.post("/api/uploadtodir", parms, config)`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/fileserverwebdoc/src/views/Manage.vue#L411
    let res = await axios.post(serverUploadApi, form, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress: function (progressEvent) {
        console.warn(progressEvent);
      },
    });

    // ref to the server side BE code `return newFixedLengthResponse("Suss");`
    // https://github.com/flyskywhy/react-native-file-server/blob/1034a33dd6d8b0999705927ad78368ca1a639add/android/src/main/java/webserver/WebServer.java#L380
    if (res.data === 'Suss') {
      console.warn('Upload Successful');
    } else if (res.data === 'fail') {
      console.warn('Upload Failed');
    }
  };

“依赖”:{“反应”:“17.0.2”、“react-native”:“0.66.1”}, 我在使用Android模拟器时遇到了这个问题。

将这些代码行添加到AndroidManifest.xml中 <应用程序 .... .... android: usesCleartextTraffic = " true " > 然后,试着在一个真正的物理设备上运行你的代码,而不是模拟器, 要在物理设备上运行,请连接usb并尝试运行NPX react-native run-android

如果您正在连接到HTTPS网站,请检查您的模拟器的互联网连接。(在我的情况下,我使用的是通过USB连接的手机模拟器,它的互联网是离线的)