Axios 发布请求未将 Content-Type 设置为 multipart/form-data

时间:2021-06-11 09:36:00

标签: reactjs post axios fetch

我正在尝试将图像从 react 上传到 cloudinary,我无法使用 axios 发出发布请求。这是代码:

 const onSubmit = async (data) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      const options = {
        headers: { "Content-Type": "multipart/form-data" },
        data: formData,
      };
      const res = await axios.post(
        `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
        options
      );
      const img = await res.json();
      const imgUrl = img.secure_url;
      data.thumbnail = imgUrl;
      console.log(data.thumbnail);
      console.log(res);
      setLoading(false);
    } else {
      data.thumbnail = "";
    }
   };

我在浏览器控制台上得到的响应: enter image description here

但是当我使用 fetch 时,我成功上传了我的图片。这是代码:

 const onSubmit = async (data) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      const options = {
        method: "POST",
        body: formData,
      };
      const res = await fetch(
        `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
        options
      );
      const img = await res.json();
      const imgUrl = img.secure_url;
      data.thumbnail = imgUrl;
      console.log(data.thumbnail);
      console.log(res);
      setLoading(false);
    } else {
      data.thumbnail = "";
    }
    };

回复:

enter image description here

我猜测我从 Web 控制台得出的结论是在标题部分,当我使用 axios 时,即使我已经将标题更改为 content-type:multipart/form-data ,它仍然作为 application/json 发送。但话说回来,我仍在学习阅读控制台日志,如果有人知道真正发生了什么,请分享您的意见!

2 个答案:

答案 0 :(得分:1)

您得到 application/json 类型是因为您将 JS 对象 options 传递给 Axios 后调用中的数据部分。

设置标题应该在 .post 方法的第三个参数中完成:

这里是修改后的代码,其中删除了 options 变量:

const onSubmit = async (data) => {
  const { files } = document.querySelector('input[type="file"]');
  console.log(data);
  if (data.files !== undefined || data.files !== null || data.files !== '') {
    setLoading(true);

    const formData = new FormData();
    formData.append('file', files[0]);
    formData.append('upload_preset', cloudinary_preset);
    const res = await axios.post(
      `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`, 
      formData, 
      {
        headers: { 'Content-Type': 'multipart/form-data' }
      }
    );
    const img = await res.json();
    const imgUrl = img.secure_url;
    data.thumbnail = imgUrl;
    console.log(data.thumbnail);
    console.log(res);
    setLoading(false);
  } else {
    data.thumbnail = '';
  }
};

Axios 文档 https://axios-http.com/docs/api_intro

<块引用>

axios.post(url[, data[, config]])

注意

我认为,当您将 FormData 类型的数据添加到 body 时,axios 会将 Content-Type 隐式设置为 multiplart/form-data

答案 1 :(得分:0)

结果是 axios 返回了一个 promise,因此我需要使用 then&catch 来使它工作,这是我的工作解决方案:

const onSubmit = async (data, e) => {
    const { files } = document.querySelector('input[type="file"]');
    console.log(data);
    if (data.files !== undefined || data.files !== null || data.files !== "") {
      setLoading(true);
      const formData = new FormData();
      formData.append("file", files[0]);
      formData.append("upload_preset", cloudinary_preset);
      await axios
        .post(
          `https://api.cloudinary.com/v1_1/${cloudinary_id}/image/upload`,
          formData
        )
        .then((result) => {
          const img = result.data;
          const imgUrl = img.secure_url;
          data.thumbnail = imgUrl;
          setLoading(false);
        })
        .catch((err) => console.log(err));
    } else {
      data.thumbnail = "";
    }

    try {
      setLoading(true);
      await authAxios
        .post("/api/project/", data)
        .then((res) => {
          console.log(res.data);
        })
        .catch((e) => {
          console.log(e);
        });
      setLoading(false);
      reset();
    } catch (err) {
      console.log(err);
    }
  };

图像上传到 cloudinary 后,我将其提取到数据中,然后将其与文本表单数据一起发送到我的 mongodb。