From 27acfab0cda4cdb50df388a63f6bc86142d730c8 Mon Sep 17 00:00:00 2001 From: Iron_Felix Date: Sat, 20 Dec 2025 03:06:12 +0300 Subject: [PATCH] fix: bad serialization of multiparted data --- .../src/pages/SettingsPage/SettingsPage.tsx | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/modules/frontend/src/pages/SettingsPage/SettingsPage.tsx b/modules/frontend/src/pages/SettingsPage/SettingsPage.tsx index d7e1a32..43bdb85 100644 --- a/modules/frontend/src/pages/SettingsPage/SettingsPage.tsx +++ b/modules/frontend/src/pages/SettingsPage/SettingsPage.tsx @@ -49,33 +49,42 @@ export const SettingsPage: React.FC = () => { // Обработка загрузки файла const handleFileChange = async (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (!file) return; + const file = e.target.files?.[0]; + if (!file) return; - setUploading(true); - setError(null); + setUploading(true); + setError(null); - const formData = new FormData(); - formData.append("file", file); + // Создаем FormData строго по спецификации + const formData = new FormData(); + formData.append("image", file); - try { - const res = await postMediaUpload({ - body: formData, - // Сбрасываем заголовок, чтобы браузер сам поставил multipart/form-data + boundary - headers: { "Content-Type": undefined as any, "X-XSRF-TOKEN": xsrfToken }, - }); + try { + // Используем fetch напрямую или убеждаемся, что клиент принимает FormData + const res = await postMediaUpload({ + // @ts-ignore - обходим строгую типизацию тела, если она ожидает объект + body: formData, + headers: { + // УДАЛЯЕМ Content-Type вообще. + // Если оставить undefined, некоторые клиенты могут подставить 'application/json'. + // Нам нужно, чтобы заголовок отсутствовал в объекте headers, + // тогда fetch сам выставит multipart/form-data с boundary. + "X-XSRF-TOKEN": xsrfToken, + }, + }); - if (res.data && res.data.id) { - setAvatarId(res.data.id); - setAvatarUrl(res.data.image_path ?? null); // Для мгновенного превью - setSuccess("Image uploaded!"); - } - } catch (err: any) { - setError("Failed to upload image"); - } finally { - setUploading(false); + if (res.data && res.data.id) { + setAvatarId(res.data.id); + setAvatarUrl(res.data.image_path ?? null); + setSuccess("Image uploaded!"); } - }; + } catch (err: any) { + console.error("Upload error:", err); + setError("Upload failed. Check if the file is an image."); + } finally { + setUploading(false); + } +}; const saveSettings = async (e: React.FormEvent) => { e.preventDefault();