React Native + Expo + Axios 文件上传不起作用,因为 axios 没有将表单数据发送到服务器

har*_*are 6 native laravel reactjs react-native axios

我正在尝试将带有 React Native 前端和 axios 的图像上传到我的后端。

这就是图像的样子

const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      allowsEditing: false,
      aspect: [9, 16],
      quality: 1,
    });

    console.log(result.uri);

    if (!result.cancelled) {
      console.log(result);
      setPhoto(result);
    }
  };
Run Code Online (Sandbox Code Playgroud)

现在你可以清楚地看到我正在使用 ImagePicker 库设置照片状态。

然后我创建一个表单数据实例:

     let img_to_upload = {  
        type: 'image/jpeg',    
        name: 'random-file-name',  
        uri: Platform.OS === 'android' ? photo.uri : photo.uri.replace('file://', ''),
    };  

    let formData = new FormData();
    formData.append("title", 'this is tandom text');
    formData.append("file", img_to_upload);
Run Code Online (Sandbox Code Playgroud)

在这里您可以清楚地看到我启动了一个 formdata 对象,然后向表单添加了两个字段。

  1. 标题
  2. 文件

最后但并非最不重要的一点是,我将其发送到服务器:

axios({
      method: 'POST',
      url: U_R_L,  
      data: formData,
      transformRequest: (d) => d, 
      headers: { 
        "Content-Type": "multipart/form-data; charset=utf-8; boundary=------random-boundary",
      }
    })
    .then((response) => {
       console.log("response : ");  
       console.log(response.data);    
    }, (error) => {
        console.log("error : "); 
        console.log(error); 
    })
    .then(() => {
      setProgress(false);
    });
Run Code Online (Sandbox Code Playgroud)

但它从不向服务器发送任何文件。

这是错误:

在此输入图像描述

但是当我使用 REST 客户端测试相同的端点时,它可以工作。

Hir*_*bod 8

Axios 的 FormData 自 v0.25 起就已被破坏。他们毫无理由地尝试优化 FormData 检测实用程序。不幸的是,对于非浏览器环境,正确的检测失败。

您现在可以在这里找到解决方法: https: //github.com/axios/axios/issues/4406#issuecomment-1048693170

长话短说

const formData = new FormData();
...
const response = await axios.post('/URL', formData, {
  headers: {
    'Content-Type': 'multipart/form-data',
  },
  transformRequest: (data, headers) => {
    return formData; // this is doing the trick
  },
});
Run Code Online (Sandbox Code Playgroud)

只需传递一个transformRequest并返回您的formData,一切都会再次神奇地“工作”。不过,这是一个解决方法(我在这个问题上花了 5 个小时),希望在即将发布的版本中得到修复。

  • 这是另一个:/sf/ask/3936470051/#71116822 关于评论,甚至只返回“数据”就足够了(这确实对我也有用) (2认同)

Fis*_*uel 0

以 BLOB 形式获取图像

 const blob = await new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onload = function () {
      resolve(xhr.response);
    };
    xhr.onerror = function (e) {
      reject(new TypeError("Network request failed"));
    };
    xhr.responseType = "blob";
    xhr.open("GET", "FILE_URI_HERE", true);
    xhr.send(null);
  });

Run Code Online (Sandbox Code Playgroud)