如何上传带有表单数据的图像?

时间:2020-05-20 05:13:00

标签: react-native expo

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

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

API使用Django Rest Framework在Django应用程序上构建。

我的代码如下: render(){ 让{图片} = 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);
}

};

2 个答案:

答案 0 :(得分:3)

我设法弄清楚了这个问题,为了其他想要类似结果的人的利益,我将其发布在这里。

  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, 

  });
}

答案 1 :(得分:1)

您可以创建FormData()对象,并将输入内容附加到此表单中。
在“照片”中,您应该在选择图像后传递URI收到的图像。
您还需要传递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,
});