向 API 请求 formData,上传图片时在 axios 中出现“网络错误”

request formData to API, gets “Network Error” in axios while uploading image

我正在向服务器发出 POST 请求以在 react-native 中使用 axios 上传图像并发送表单数据。我得到 "Network Error"。我也尝试获取但没有 work.using 为 select image.in 邮递员 api 工作正常

反应原生图像选择器 liberary
        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);
    });

"react-native": "0.62.1", "react": "16.11.0", "axios": "^0.19.2",

奇怪的解决方案我必须删除调试文件夹 在 android ->app->source->debug

然后重新启动应用程序 它解决了我的问题。我认为这是缓存问题。

项目在 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

我遇到了这个问题,通过评论 43 行解决了 android/src/debug/.../.../ReactNativeFlipper.java

// builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));

你能测试一下吗?

我遇到了同样的问题。以下步骤对我有用。

  1. 更新FLIPPER_VERSION=0.52.0最新
  2. 对于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。

反应本机解决方案

如果您在 React Native 中使用 AxiosFetch,并且在上传文件或数据时得到 Network Error

尝试commenting /android/app/src/main/java/com/{your_project}/MainApplication.java

下方的行

位于40-50线附近

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

https://github.com/facebook/react-native/issues/28551

我遇到的问题与您提到的很接近,是我在使用图像选择器并尝试使用 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 类型。例如:.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()
});

我希望这有助于解决您的问题:)

更改此行:form_data.append('file', data);

到form_data.append('file',JSON.stringify(数据));

来自 https://github.com/react-native-image-picker/react-native-image-picker/issues/798

您需要将此 uesCleartextTraffic="true" 添加到 android/app/src/main/AndroidManifest 目录中的 AndroidManifest.xml 文件中。xml

然后,由于 Flipper Network 的问题。

我评论了 initializeFlipper(this, getReactNativeHost().getReactInstanceManager())

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

此外,注释掉此文件中的第 43 行 android/app/src/debug/java/com/**/ReactNativeFlipper.java

第 43 行:builder.addNetworkInterceptor(新的 FlipperOkhttpInterceptor(networkFlipperPlugin));

如果使用 expoexpo-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

})

就我而言,调试了一段时间后,问题出在 nginx 上。
图片“太大”了。

我必须向 Kubernetes 入口添加注释:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 20m
....

调试有点棘手,因为请求从未通过负载平衡器 (nginx) 到达 Api 服务。 “网络错误”消息也没有太大帮助。

我正在使用 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,而我进入 resulturi 格式为 /data/path/to/file.jpeg。我也尝试将 file:// 附加到 uri 的开头,但它没有用。

然后我将 copyToCacheDirectory 设置为 false,我在 result 中得到的 uri 格式为 content://path/to/file.jpeg。这并没有在 axios 中造成任何 Network Error

我也遇到过这个错误。我发现我得到这个错误是因为文件路径错误,axios找不到文件。当 uri 错误时,这是​​一条奇怪的错误消息,但这就是实际发生的情况。因此,仔细检查文件的 uri 即可解决问题。主要考虑file://.

就我而言,解决方案是更改为

const headers = {
    accept: 'application/json',
    'content-type': 'multipart/form-data',
};