向 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 中使用AxiosFetch,并且在上传文件或数据时得到Network Error

尝试从/android/app/src/main/java/com/your_project/MainApplication.javacommenting 下一行

它位于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】:

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

)

【讨论】:

完整解答如何上传图片或视频***.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 中出现“网络错误”的主要内容,如果未能解决你的问题,请参考以下文章

前端向后端发送请求(FormData)

通过JS创建FormData实现上传多张图片

通过JS创建FormData实现上传多张图片

通过JS创建FormData实现上传多张图片

通过JS创建FormData实现上传多张图片

FormData如何向后端传递数组