React Native Expo:android 上的网络错误
React Native Expo: Network error on android
我在我的应用程序中使用了 axios。当我在打开应用程序后第一次发出 post 请求时,它失败并出现以下错误。从第二次开始,它没有任何问题。
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/ 连接到真实服务器的真实 android 设备上。同样的 post 请求我尝试在 kotlin 中创建一个 Native 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 地址中。
- 从 localhost 更改为您的 ip
- 添加http://
http://192.168.43.49:3000/user/
解决方案 2
我遇到了同样的问题,它发生在 Android,但在 IOS 中运行良好。
我猜这个问题是关于 Flipper Network 的。
有一段时间,我评论了
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
文件的 mime 类型为 image/png
。我们不必手动执行此操作。相反,您可以使用名为 mime.
的非常著名的 npm 包
最终的工作解决方案是:
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()
});
如果有人不喜欢被赞成的答案或仍然面临这个问题,那么我的回答可能会有所帮助。请确保您的 emulator/device 时间与真实世界时间相同以避免证书验证错误,否则请手动设置正确的时间并重新加载应用程序。
我在我的应用程序中使用了 axios。当我在打开应用程序后第一次发出 post 请求时,它失败并出现以下错误。从第二次开始,它没有任何问题。
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/ 连接到真实服务器的真实 android 设备上。同样的 post 请求我尝试在 kotlin 中创建一个 Native 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 地址中。
- 从 localhost 更改为您的 ip
- 添加http://
http://192.168.43.49:3000/user/
解决方案 2
我遇到了同样的问题,它发生在 Android,但在 IOS 中运行良好。 我猜这个问题是关于 Flipper Network 的。
有一段时间,我评论了
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
文件的 mime 类型为 image/png
。我们不必手动执行此操作。相反,您可以使用名为 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()
});
如果有人不喜欢被赞成的答案或仍然面临这个问题,那么我的回答可能会有所帮助。请确保您的 emulator/device 时间与真实世界时间相同以避免证书验证错误,否则请手动设置正确的时间并重新加载应用程序。