React Native Expo:安卓上的网络错误



我在我的应用程序中使用axios。当我在打开应用程序后第一次发出发布请求时,它失败并出现以下错误。从第二次开始,它可以毫无问题地工作。

Network Error
- node_modules/axios/lib/core/createError.js:15:17 in createError
- node_modules/axios/lib/adapters/xhr.js:81:22 in handleError
- node_modules/event-target-shim/dist/event-target-shim.js:818:20 in EventTarget.prototype.dispatchEvent
- node_modules/react-native/Libraries/Network/XMLHttpRequest.js:600:10 in setReadyState
- node_modules/react-native/Libraries/Network/XMLHttpRequest.js:395:6 in __didCompleteResponse
- node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js:189:10 in emit
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:416:4 in __callFunction
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:109:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:364:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
* [native code]:null in callFunctionReturnFlushedQueue

我正在通过 http://my_ip:my_port/连接到真实服务器的真实安卓设备上运行。我尝试在 kotlin 中创建一个原生 android 项目,它的工作没有任何问题

这是我的代码:

const upload = () => {
setAnalyzing(true);
axios.post(URL_PREDICT, formBody(), {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(handleSuccess)
.catch(handleFail);
}
const formBody = () => {
const photo = {
uri: image,
type: 'image/jpeg',
name: 'photo.jpg',
};
const form = new FormData();
form.append("file", photo);
return form;
};
const handleFail = (error) => {
console.log(error)
console.log(error?.response?.data);
setAnalyzing(false);
toggle();
alert("ERROR " + error);
};
const handleSuccess = response => {
console.log('success...');
setAnalyzing(false);
toggle();
console.log(response);
navigation.navigate('Result', response);
};

知道是什么原因造成的吗?

解决方案 1

确保"http://">在您的 URL 地址中。

  1. 本地主机更改为您的IP
  2. 添加http://

http://192.168.43.49:3000/user/

解决方案 2

我遇到了同样的问题,它发生在 Android 中,但在 IOS 中运行良好。 我猜这个问题是关于鳍状网络。

有一段时间,我评论说

initializeFlipper(this, getReactNativeHost().getReactInstanceManager())

在此文件中/android/app/src/main/java/com/{your_project}/MainApplication.java

解决方案 3

谁还在为这个问题而苦苦挣扎。 这是因为Flipper网络插件而发生的。 我禁用了它,一切正常。

我完成这项工作的解决方法是注释掉第 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/app/src/debug/java/com/**/ReactNativeFlipper.java

解决方案 4

不需要添加Access-Control-Expose-Headers.

需要这个:

headers:{
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json'}
}

我调整你的服务器,它有效。

我认为您正在使用expo-image-picker.

这里有两个独立的问题在起作用。假设我们从image-picker获取imageUri,那么我们将使用以下代码行从前端上传。

const formData = new FormData();
formData.append('image', {
uri : imageUri,
type: "image",
name: imageUri.split("/").pop()
});

第一个问题是imageUri本身。如果假设照片路径是/user/.../path/to/file.jpg.然后 android 中的文件选择器会给出imageUri值作为file:/user/.../path/to/file.jpg而 iOS 中的文件选择器会给出imageUri值作为file:///user/.../path/to/file.jpg

第一个问题的解决方案是在android的formData中使用file://而不是file:

第二个问题是我们没有使用正确的mime-type。它在iOS上运行良好,但在Android上无法正常工作。更糟糕的是,文件选择器包将文件类型作为"图像"给出,并且没有给出正确的 mime 类型。

解决方案是在字段类型的 formData 中使用适当的mime-type。例如:.jpg文件的 mime 类型将是image/jpeg,对于.png文件将是image/png。我们不必手动执行此操作。相反,你可以使用一个非常著名的 npm 包,称为 mime。

最终的工作解决方案是:

import mime from "mime";
const newImageUri =  "file:///" + imageUri.split("file:/").join("");
const formData = new FormData();
formData.append('image', {
uri : newImageUri,
type: mime.getType(newImageUri),
name: newImageUri.split("/").pop()
});

如果有人不喜欢投票的答案或仍然面临这个问题,那么我的答案可能会有所帮助。请确保模拟器/设备时间与实际时间相同,以避免证书验证错误,否则手动设置正确的时间并重新加载应用。

在尝试使用模拟器中的 expo 从反应本机应用程序向我的 rust actix Web 服务器发送 API 请求时,我遇到了同样的问题。 在花了几个小时研究这个问题并且无法找到修复它的方法后,我在 ngrok 中找到了解决方案。它从本地服务器建立隧道以打开网络,因此基本上您可以从您的 RN 应用程序调用您的 api 端点,就好像它不会在您的本地主机中运行一样。

错误立即得到修复。希望它有所帮助,即使我知道这不是修复程序,而是解决您问题的解决方法。

万一有人再次遇到麻烦..我发现对于 android,ip 需要为 10.0.2.2,但对于 ios,它必须是 127.0.0.1。

下面的代码允许您独立设置它们:

import { Platform } from 'react-native';
const LOCALHOST = Platform.OS === 'ios' ? 'http://127.0.0.1:8000' : 'http://10.0.2.2:8000';
export const API_BASE_URL = LOCALHOST + '/api/v1/';

相关内容

  • 没有找到相关文章

最新更新