【问题标题】:Network request failed on react native upload image响应本机上传图像的网络请求失败
【发布时间】:2020-06-18 13:22:33
【问题描述】:

我正在尝试从 react native 捕获图像并将其上传到服务器,但是当我发出 http 请求时出现以下错误:

[TypeError:网络请求失败]

这是我的代码,我已经按照本教程进行操作:

https://heartbeat.fritz.ai/how-to-upload-images-in-a-react-native-app-4cca03ded855

import React from 'react';
import {View, Image, Button} from 'react-native';
import ImagePicker from 'react-native-image-picker';

export default class App extends React.Component {
  state = {
    photo: null,
  };

  createFormData = (photo) => {
    const data = new FormData();

    data.append('photo', {
      name: photo.fileName,
      type: photo.type,
      uri:
        Platform.OS === 'android'
          ? photo.uri
          : photo.uri.replace('file://', ''),
    });

    data.append('id', 1);
    return data;
  };

  handleChoosePhoto = () => {
    const options = {
      noData: true,
    };
    ImagePicker.launchImageLibrary(options, (response) => {
      if (response.uri) {
        this.setState({photo: response});
      }
    });
  };

  handleUploadPhoto = () => {
    fetch('http://192.168.1.104:3000/', {
      method: 'POST',
      body: this.createFormData(this.state.photo),
    })
      .then((response) => response.text())
      .then((response) => {
        console.log('upload success', response);
      })
      .catch((error) => {
        console.log('upload error', error);
      });
  };

  render() {
    const {photo} = this.state;
    return (
      <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
        {photo && (
          <React.Fragment>
            <Image
              source={{uri: photo.uri}}
              style={{width: 300, height: 300}}
            />
            <Button title="Upload" onPress={this.handleUploadPhoto} />
          </React.Fragment>
        )}
        <Button title="Choose Photo" onPress={this.handleChoosePhoto} />
      </View>
    );
  }
}

我试过了:

  • 将“Content: multipart/form-data”添加到 http 请求标头
  • 将 Accept: Accept: application/json" 添加到 http 请求标头

我注意到请求失败,只有当我将照片对象添加到“FormData”时,即当我删除以下代码时http请求才能正常运行:

data.append('photo', {
      name: photo.fileName,
      type: photo.type,
      uri:
        Platform.OS === 'android'
          ? photo.uri
          : photo.uri.replace('file://', ''),
    });

编辑 02-07-2020

我终于在这里找到了解决方案:

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

【问题讨论】:

  • 我正在使用以下包 "react": "16.11.0", "react-native": "0.62.2", "react-native-image-picker": "^2.3 .1" 我正在开发的手机是小米红米 Note 5
  • 你试过添加'file://' + photo.path 作为安卓的uri吗?
  • 由于“网络请求失败”错误而到达这里的人可能有兴趣阅读this

标签: javascript node.js react-native fetch


【解决方案1】:

第一个问题是 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-type。

解决方案是在字段类型的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()
}); 

【讨论】:

  • 要获取有关此解决方案的更多信息,请点击此处:forums.expo.dev/t/…
  • 您还必须通过运行安装 mime - expo install mime 或 npm install mime
【解决方案2】:

This solution 也可以:

我在 react-native 版本 0.62 的项目中遇到了同样的问题。 我将脚蹼更新为“0.41.0”,它工作正常。

在 gradle.properities 中

FLIPPER_VERSION=0.41.0

gradle.properties 位于PROJECT_ROOT/android

【讨论】:

    【解决方案3】:
    const URL = "ANY_SERVER/upload/image"
      const xhr = new XMLHttpRequest();
      xhr.open('POST', url); // the address really doesnt matter the error occures before the network request is even made.
      const data = new FormData();
      data.append('image', { uri: image.path, name: 'image.jpg', type: 'image/jpeg' });
    
      xhr.send(data);
      xhr.onreadystatechange = e => {
        if (xhr.readyState !== 4) {
          return;
        }
    
        if (xhr.status === 200) {
          console.log('success', xhr.responseText);
        } else {
          console.log('error', xhr.responseText);
        }
      };
    

    【讨论】:

      【解决方案4】:

      几天前遇到了类似的问题。 我的问题是 photo.type 返回了不正确的类型。所以我只是手动添加它。

      fd.append('documentImages', {
            name: getImgId(img.uri) + '.jpg',
            type: 'image/jpeg',
            uri: Constants.platform.android
              ? img.uri
              : img.uri.replace('file://', ''),
          })
      

      【讨论】:

      • 这些是我打印图像的一些属性时得到的值 fileName: IMG-20200617-WA0022.jpg type: image /jpeg uri: content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FWhatsApp%2FMedia%2FWhatsApp%20Images%2FIMG-20200617-WA0022.jpg
      • de post 失败时是否有任何错误消息?不要只是 consol.log 错误。检查错误对象,也许你会在那里找到有用的信息
      【解决方案5】:
      const launchCamera = () => {
        let options = {
          storageOptions: {
            skipBackup: true,
            path: "images",
          },
        };
        ImagePicker.launchCamera(options, (response) => {
          console.log("Response = ", response);
          if (response.didCancel) {
            console.log("User cancelled image picker");
          } else if (response.error) {
            console.log("ImagePicker Error: ", response.error);
          } else if (response.customButton) {
            console.log("User tapped custom button: ", response.customButton);
            alert(response.customButton);
          } else {
            const source = { uri: response.uri };
            console.log(
              "response in image pleae chec nd xcjn",
              JSON.stringify(response)
            );
            this.setState({
              filePath: response,
              fileData: response.data,
              fileUri: response.uri,
            });
          }
          imageUpload(response);
        });
      };
      
      const imageUpload = (imageUri) => {
        console.log('imageuril',imageUri);
        const newImageUri =  "file:///" + imageUri.assets[0].uri.split("file:/").join("");
        const imageData = new FormData()
        imageData.append("file", {
          uri: newImageUri,
          type: mime.getType(newImageUri),
          name: newImageUri.split("/").pop()
        })
        console.log("form data", imageData)
        axios({
          method: 'post',
          url: 'https://example.com/admin/api/v1/upload_reminder/1',
          data: imageData
        })
          .then(function (response) {
            console.log("image upload successfully", response.data)
          }).then((error) => {
            console.log("error riased", error)
          })
      
      }
      

      使用此代码 100% 有效

      【讨论】:

      • 从“mime”导入mime;安装这个插件 100% 代码工作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 2019-08-19
      • 2020-11-21
      • 2018-03-01
      • 2019-02-09
      • 2019-11-28
      • 1970-01-01
      相关资源
      最近更新 更多