【问题标题】:How can I upload image with form data?如何上传带有表单数据的图像?
【发布时间】:2020-05-20 05:13:00
【问题描述】:

我正在通过 Expo 学习 React Native。对于一个测试项目,我有一个名为“创建配置文件”的屏幕,我试图在其中添加在 Expo 图像选择器上选择的图像以及其他文本输入 - 位置、描述。如何将输入与图像选择器中的图像结合起来?

我目前的猜测是对图像使用 base64 或将图像输入设置为“this.state.image”以从选取器中调用 image:uri。虽然我可能会走错路。另一种选择是使用 Content-Type:multipart-form/data 尽管在尝试时它不会将任何数据发布到 API 调用。

API 是基于使用 Django Rest Framework 的 Django 应用程序构建的。

我的代码如下: 使成为() { 让 { image } = this.state;

function handleSubmit(props) {
  fetch('<API URL HERE>', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    }, 
    body:JSON.stringify({
      'location': this.state.location,
      'description': this.state.description,
      //user image field and input below
      'user_image':this.state.image


    })
  });
} 

图片选择器

_pickImage = async () => {
try {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
  });
  if (!result.cancelled) {
    const image = result.uri;
    this.setState({ image: result.uri });
  }

  console.log(result);
} catch (E) {
  console.log(E);
}

};

【问题讨论】:

    标签: react-native expo


    【解决方案1】:

    我只是设法弄清楚了这一点,为了其他想要类似结果的人的利益,我已将其发布在这里。

    1. 对于图像选择器,您需要添加其他变量,例如图像 uri、文件名和文件类型。

        _pickImage = async () => {
         try {
         let result = await ImagePicker.launchImageLibraryAsync({
           mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
         });
           if (!result.cancelled) {
      this.setState({ image: result.uri });
      
      let localUri = result.uri;
      let filename = localUri.split('/').pop();
      
      // Infer the type of the image
      let match = /\.(\w+)$/.exec(filename);
      let type = match ? `image/${match[1]}` : `image`;
      
      this.setState({ localUri: result.uri });
      this.setState({ filename: filename });
      this.setState({ type: type });
      
        }
      

    然后对于表单数据,您必须调整图像字段以在将它们与其他字段一起提交时包含这些变量。

        let formData = new FormData();
        formData.append('location',this.state.location);
        formData.append('description',this.state.description);
        formData.append('member_unique','IEQ'); 
        formData.append('user_image', {type:type, uri:uri, name:filename});
    
     function handleSubmit(props) {
      fetch('<posting api>', {
        method: 'POST',
        body:formData, 
    
      });
    }
    

    【讨论】:

    • 看起来你在 user_image 对象中传递 URI 字符串,服务器将如何获取实际文件(图像/视频)来上传它?
    • 如果 uri 是“文件系统 uri”,@Furquan FormData 或 fetch 似乎知道如何做到这一点。但在 Android 上,情况并非总是如此,您会得到一个 FormData / fetch 无法读取的 ContentProvider uri。
    【解决方案2】:

    您可以创建FormData() 对象并将您的输入附加到此表单。
    在照片中,您应该通过URIof 选择图像后收到的图像。
    您还需要传递 nametype 参数才能进入 Django。
    将标头 multipart/form-dataPOST 请求一起使用。
    您可能需要 CSRF TOKEN 向 Django 发送 POST 请求

    const formData = new FormData();
    formData.append("detectImg", {
        uri: image.uri,
        name: "image",
        type: "image/jpg",
    });
    const response = await fetch("BACKEND_URL", {
        method: "POST",
        headers: {
             "Content-Type": "multipart/form-data",
        },
        body: formData,
    });
    
    

    【讨论】:

    • 费林,你的回答确实有帮助。我已经对其进行了一些调整和补充,现在可以使用了。谢谢。
    猜你喜欢
    • 2016-09-05
    • 2018-09-03
    • 2015-12-15
    • 1970-01-01
    • 2016-12-14
    • 2012-08-08
    • 1970-01-01
    • 2018-09-11
    • 2016-04-13
    相关资源
    最近更新 更多