Запрос на публикацию Axios не устанавливает Тип содержимого в составные/данные формы

#reactjs #post #axios #fetch

Вопрос:

Я пытаюсь загрузить изображение в cloudinary из react, я не могу сделать запрос на публикацию с помощью 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 = "";
    }
   }; 

ответ, который я получил на консоли браузера :
введите описание изображения здесь

Но когда я использую 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 = "";
    }
    }; 

ответы :

введите описание изображения здесь

Мое предположение, которое я делаю из веб-консоли , касается заголовков, когда я использую axios, даже если я уже изменил заголовки на тип содержимого:составные/данные формы, они все еще отправляются как приложение/json. Но опять же , я все еще учусь читать журнал консоли, если кто-то знает, что происходит на самом деле, пожалуйста, поделитесь своим мнением!

Ответ №1:

Вы получаете application/json тип, потому что передаете объект JS options в часть данных в своем почтовом вызове Axios.

Настройка заголовков должна выполняться в 3-м аргументе .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[, данные[, конфигурация]])

записка

Я думаю, что когда вы добавляете данные типа FormData в тело, axios будет Content-Type multiplart/form-data выглядеть неявно.

Комментарии:

1. Я понял это , проблема была в моей логике! оказывается , что при использовании axios он возвращает обещание, поэтому мне нужно использовать then amp; catch. И вы правы, axios автоматически видит содержимое как составные данные/данные формы, потому что, когда я удаляю конфигурацию заголовков, я все равно смогу сделать запрос на публикацию! код, опубликованный ниже.

2. Да, он возвращает обещание, но вам не нужно использовать then/catch. Вы также можете использовать await , как вы это делали. await сделано для обработки обещания 🙂 так что попробуйте еще раз await и посмотрите, была ли FormData вашей единственной проблемой.

Ответ №2:

Оказывается , axios возвращает обещание, поэтому мне нужно использовать thenamp;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 вместе с данными текстовой формы.