向 API 请求 formData,上传图片时在 axios 中出现“网络错误”
Posted
技术标签:
【中文标题】向 API 请求 formData,上传图片时在 axios 中出现“网络错误”【英文标题】:request formData to API, gets “Network Error” in axios while uploading image 【发布时间】:2020-07-25 06:49:09 【问题描述】:我正在向服务器发出 POST 请求以上传图像并在 react-native 中使用 axios 发送表单数据。我收到“网络错误”。我也尝试获取但没有任何效果。使用 react native image picker libeary for select image.in postman api 工作正常
formData.append('title', Title);
formData.append('class_id', selectClass._id)
formData.append('subject_id', checkSelected)
formData.append('teacher_id', userId)
formData.append('description', lecture);
formData.append('type', 'image');
var arr=[];
arr.push(imageSource)
arr.map((file,index)=>
formData.append('file',
uri:file.path,
type:file.type,
name:file.name
)
)
axios(
method: 'post',
url: URL + 'admin/assignment/create',
data: data,
headers:
"content-type": "multipart/form-data",
'x-auth-token': token,
,
)
.then(function (response)
//handle success
console.log('axios assigment post',response);
)
.catch(function (response)
//handle error
console.log('axios assigment post',response);
);
【问题讨论】:
这里是使用 axios ***.com/a/67987558/13789135上传图片或视频的简单方法 【参考方案1】:项目在 app > source > debug in react native > 0.62 下保留 Flipper java 文件。 Flipper Network 存在问题,导致您的情况出现问题。如果您删除调试文件夹,您将无法使用 Flipper 调试 android,因此最好的解决方案是将 android > gradle.properties 中的 Flipper 版本升级到 0.46.0 以解决问题。
你可以用这一行来改变它
FLIPPER_VERSION=0.46.0
react-nativeandroid
【讨论】:
【参考方案2】:我遇到了同样的问题。以下步骤对我有用。
-
更新 FLIPPER_VERSION=0.52.0 最新
formData
代码如下:
let formData = new FormData();
let file =
uri: brand.uri,
type: 'multipart/form-data',
name: brand.uri
;
formdata.append('logo', file);
类型必须是'multipart/form-data'作为post header。
【讨论】:
类型不应该是multipart/form-data
。相反,它应该是照片类型,例如:image/jpeg
。【参考方案3】:
反应原生解决方案
如果您在React Native
中使用Axios
或Fetch
,并且在上传文件或数据时得到Network Error
。
尝试从/android/app/src/main/java/com/your_project/MainApplication.java
到commenting
下一行
它位于40-50
线附近
initializeFlipper(this, getReactNativeHost().getReactInstanceManager())
https://github.com/facebook/react-native/issues/28551
【讨论】:
这个解决方案对我有用,但同时,我担心评论这条线会影响? 不,我已经在我的项目中这样做了,现在它正在生产中,所以不用担心 我还需要评论ReactNativeFlipper.java
中的行吗?
尝试遵循此答案,如果不起作用,请转到 ReactNativeFlipper.java
并评论第 43 行 FlipperOkhttpInterceptor
【参考方案4】:
我面临的与您提到的问题接近的问题是,我在使用图像选择器并尝试使用 axios 上传文件时遇到 NetworkError。它在 iOS 中运行良好,但在 android 中无法运行。
这就是我解决问题的方法。
这里有两个独立的问题在起作用。假设我们从 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 类型。它在 iOS 上运行良好,但在 Android 上却不行。更糟糕的是,文件选择器包将文件类型指定为“图像”,但没有提供正确的 mime 类型。
解决方法是在字段类型的formData中使用适当的mime-type。例如:.jpg 文件的 mime-type 为 image/jpeg,.png 文件的 mime-type 为 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()
);
我希望这有助于解决您的问题:)
【讨论】:
偶然发现了同样的哑剧类型的东西。这真是令人惊讶。【参考方案5】:"react-native": "0.62.1", “反应”:“16.11.0”, "axios": "^0.19.2",
奇怪的解决方案我必须删除调试文件夹 在android->app->source->debug
然后重新启动应用程序 它解决了我的问题。我认为是缓存问题。
【讨论】:
github.com/facebook/react-native/issues/28551 @srinivas 您可以查看此链接,也许它可以解决您的问题 通过更新 FLIPPER_VERSION=0.41.0 看到该页面后,我理解它应该得到解决,但如果我更新应用程序甚至无法打开。 因为这个问题,我浪费了 2 天时间。感谢上帝,现在它工作正常。感谢您提供此解决方案@GovindMaheshwari。 不工作可能会删除 androidmanifest.xml【参考方案6】:我遇到了这个问题,并通过注释 43 行来解决它 android/src/debug/.../.../ReactNativeFlipper.java
// builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
你能测试一下吗?
【讨论】:
修改最少的正确答案。虽然路径名是 android/app/src/..... .【参考方案7】:我最近将我的 Flipper 更新到了新版本,它运行良好。
版本在 gradle.properties 文件中定义
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.83.0
更改flipper版本后务必清理android文件夹中的项目。
./gradlew clean
@Mahmonir Bakhtiyari 提出的解决方案是一种解决方法,如果您无法更新您的 Flipper 版本,因为 Flipper 中的网络调试器将停止工作。
#### android/src/debug/.../.../ReactNativeFlipper.java
//builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
更多信息可以在以下问题中找到:
https://github.com/facebook/flipper/issues/993
https://github.com/facebook/react-native/issues/28551
【讨论】:
【参考方案8】:更改这一行:form_data.append('file', data);
到form_data.append('file', JSON.stringify(data));
来自https://github.com/react-native-image-picker/react-native-image-picker/issues/798
您需要将此 uesCleartextTraffic="true" 添加到目录 android/app/src/main/AndroidManifest.xml 中的 AndroidManifest.xml 文件中
那么,由于 Flipper Network 的问题。
我评论了 initializeFlipper(this, getReactNativeHost().getReactInstanceManager())
在这个文件/android/app/src/main/java/com/your_project/MainApplication.java
另外,注释掉这个文件 android/app/src/debug/java/com/**/ReactNativeFlipper.java 中的第 43 行
line43: builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
【讨论】:
【参考方案9】:如果使用expo
和expo-image-picker
,则问题仅在于图像类型,没有其他问题。
在最新的更新中,他们删除了与路径相关的错误(正如其他答案提到的那样,更改路径的开头对于旧版本是正确的)。
现在要解决问题,我们只需要更改类型,其他答案中提到使用 mime 可以正常工作;
import mime from 'mime'
const data = new FormData();
data.append('image',
uri: image.uri,
name: image.uri.split('/').pop() // getting the text after the last slash which is the name of the image
type: mime.getType(image.uri) // image.type returns 'image' but mime.getType(image.uri) returns 'image/jpeg' or whatever is the type
)
【讨论】:
完整解答如何上传图片或视频***.com/a/67987558/13789135【参考方案10】:在我的情况下,调试一段时间后,问题出在 nginx 中。 图片“太大”。
我必须向 Kubernetes 入口添加注释:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
....
调试有点棘手,因为请求从未通过负载均衡器 (nginx) 到达 Api 服务。 “网络错误”消息也没有太大帮助。
【讨论】:
【参考方案11】:我正在使用 Expo SDK 42(react-native v0.63)。我正在使用expo-document-picker
库来选择文档并上传到服务器。
这是我用来打开选择器并获取有关文件的元数据的代码。
const result = await DocumentPicker.getDocumentAsync(
type: 'image/*',
copyToCacheDirectory: false,
multiple: false,
);
if (result.type === 'success')
const name_split = result.name.split('.');
const ext = name_split[name_split.length - 1];
// result.uri = 'file://' + result.uri;
result.type = helper.get_mime_type(ext);
delete result.size;
(您可以编写函数以从文件扩展名中获取 mime 类型或使用 npm 中的某些库)
这是我用来将文件上传到服务器的代码:
const formdata = new FormData();
formdata.append('custom_param', 'value');
formdata.append('file', result); // 'result' is from previous code snippet
const headers =
accept: 'application/json',
'content-type': 'multipart/form-data',
;
const opts =
method: 'POST',
url: 'your backend endpoint',
headers: headers,
data: formdata,
;
return await axios.request(axiosopts);
上面的代码是工作代码。我想解释一下我最初做错了什么导致 axios 中出现Network Error
。
我最初将copyToCacheDirectory
设置为true
,而我在result
中得到的uri
格式为/data/path/to/file.jpeg
。我还尝试将file://
附加到uri
的开头,但没有成功。
然后我将copyToCacheDirectory
设置为false
,而我在result
中得到的uri
格式为content://path/to/file.jpeg
。这并没有导致 axios 中出现任何Network Error
。
【讨论】:
【参考方案12】:我也遇到过这个错误。我发现我收到此错误是因为文件路径错误并且 axios 找不到该文件。当 uri 错误时,这是一个奇怪的错误消息,但这就是实际发生的情况。因此,仔细检查文件的 uri 将解决问题。主要考虑file://。
【讨论】:
以上是关于向 API 请求 formData,上传图片时在 axios 中出现“网络错误”的主要内容,如果未能解决你的问题,请参考以下文章