#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 вместе с данными текстовой формы.