https://avoc-o-d.tistory.com/85
[React/JS] ๋ฒํผ ํด๋ฆญ ์ ์ด๋ฏธ์ง ์ ๋ก๋, ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ตฌํํ๊ธฐ (ํ์ผ ์ ํ ๋ฒํผ ์ ๊ฑฐ, ์ปค์คํ ํ๊ธฐ)
๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ด ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค. 1. FileReader๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์ 2. URL API๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์ ๐ (์ถ์ฒ) ๊ตฌํํด๋ด ์๋ค! 00. - ํ์ผ ์ ํ ๋ฒํผ ์ ๊ฑฐ ์ฐ์ , input type="file"
avoc-o-d.tistory.com
์๋ ํ์ผ ์ ๋ก๋์ ๊ดํด ์์ฑํ ๊ธ์ ๋๋ค.
์ง๊ธ ์ฐ๊ณ ์๋ ๊ธ์, API ์์ฒญ์ ํ ๋ Request body์ ํ์ผ ๊ฐ์ฒด๋ฅผ ๋ณด๋ด์ค์ผ ํ๋ ์ํฉ์ ์ํด ์์ฑํ ๊ธ์ ๋๋ค!
json์ผ๋ก๋ ํ์ผ ๊ฐ์ฒด๋ฅผ ์ฝ์ ์ ์๊ธฐ ๋๋ฌธ์ FormData๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ธฐ๋ก ํฉ์๋ค!!!
00. ํ์ผ ๊ฐ์ฒด
ํ์ผ ๊ฐ์ฒด๋ ์์ ๊ฐ์ด ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
์ด๋ฏธ์ง ์ด๋ฆ์ธ name : ์๋ณด์นด๋.jpg
์ด๋ฏธ์ง ํ์์ธ type : image/jpeg
๋ฑ๋ฑ.. ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค!
01. Content-Type: "multipart/form-data"
axios, fetch ๋ฑ์ ์๋ฒ ํต์ ํจ์๋ FormData ๊ฐ์ฒด๋ฅผ body๋ก ๋ฐ์ต๋๋ค.
์ด๋ ์น ๋ธ๋ผ์ฐ์ ๊ฐ ๋ณด๋ด๋ HTTP ๋ฉ์์ง๋ Content-Type ์์ฑ์ด multipart/form-data๋ก ์ง์ ๋ ํ ์ ํด์ง ํ์์ ๋ฐ๋ผ ์ธ์ฝ๋ฉ ํ์ฌ ์ ์กํฉ๋๋ค.
await axios
.post( API ์ฃผ์ , ๋ณด๋ผ ๋ฐ์ดํฐ , {
headers: {
// ํ์ผ ๋ฑ๋ก์ ์ํด ํค๋์ Content-Type ํ๋์ ๋ช
์
"Content-Type": "multipart/form-data",
},
})
.then((response) => {
...
});
multipart/form-data ๐ค
- post ์ธ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅ!
- ๋ชจ๋ ๋ฌธ์๋ฅผ ์ธ์ฝ๋ฉํ์ง ์์์ ๋ช ์
๊ทธ๋ฐ๋ฐ, FormData๋ฅผ ๋ณด๋ผ ๋ header ๋ถ๋ถ์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋์ผ๋ก ์ค์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ด ๋ฐ๋ก ์ง์ ํด์ค ํ์๊ฐ ์์ต๋๋ค!
02. FormData ๊ฐ์ฒด์ ๋ฐ์ดํฐ ๋ด๊ธฐ
HTML์ <form> ํ๊ทธ๋ฅผ ํตํด input ๊ฐ์ ์๋ฒ์ ์ ์กํ์ง๋ง, JS ์์ FormData() ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ ๋๊ฐ์ด ์ ์ก ๊ฐ๋ฅํฉ๋๋ค.
const formData = new FormData();
formData.append(name, value); // name๊ณผ value๋ฅผ ๊ฐ์ง form ํ๋๋ฅผ ์ถ๊ฐ
formData.append("age", "111"); // <input name="age" value="111"> ์ ๊ฐ์ ์๋ฏธ
03. FormData ์ํ
์ด๋ ๊ฒ,,, append๋ฅผ ํตํด formdata์ ๋ง์ ๋ฐ์ดํฐ๊ฐ ๋ด๊ฒผ๋ค๊ณ ํฉ์๋ค!
formdata๋ฅผ ์ฝ์์ ์ฐ์ด๋ณผ๊น์??
์์ ๊ฐ์ด ๋ฃ์ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์๋ํ๋ฉด JS ์์ FormData ๊ฐ์ฒด๋ XMLHttpRequest ์ ์ก์ ์ํ ํน์ํ ๊ฐ์ฒด ํํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ ์ง๋ง, ํ์ธ์ ํ ์ ์์ด์ผ ํ๋๊น! ํ์ธํ๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค!!!
// key ๊ฐ์ ์ํ
let keys = formData.keys();
for (const pair of keys) {
console.log(pair);
}
// ํผ ๊ฐ์ฒด values ๊ฐ์ ์ํ
let values = formData.values();
for (const pair of values) {
console.log(pair);
}
// ํผ ๊ฐ์ฒด key ์ value ๊ฐ์ ์ํ
let entries = formData.entries();
for (const pair of entries) {
console.log(pair[0], " : ", pair[1]);
}
04. ์๋ฒ์ ์ ์ก
์๋์ ๊ฐ์ด ์๋ฒ์ธก์์ ์ ํด์ง ํ์์ ๋ฐ๋ผ name, value๋ฅผ ์ ๋ง์ถ์ด ์์ฑํด์ฃผ์๋ฉด ๋ฉ๋๋ค!
// dataToSubmit : ์๋ฒ์ ๋ณด๋ผ ์ด๋ฏธ์ง ํ์ผ์ด ๋ด๊ธด ๊ฐ์ฒด
// ์๋ฅผ ๋ค์ด,
// dataToSubmit= {
// image : ์ด๋ฏธ์ง ํ์ผ -> file
// }
async function submitTest(dataToSubmit = {}) {
const formData = new FormData();
formData.append("images", dataToSubmit.image);
let data;
try {
await axios
.post( API์ฃผ์ , formData)
.then((response) => {
data = response.data;
});
return data;
} catch (error) {
...
}
}
}
05. ํ ๋ฒ์ ์ฌ๋ฌ ํ์ผ ์ ์ก
์๋ฒ์ธก์ ์ค๊ณ์ ๋ฐ๋ผ ์๋์ ๊ฐ์ด ๋๊ฐ์ name์ ์ฌ๋ฌ ๊ฐ๋ฅผ ์ ์กํ ์ ์์ต๋๋ค.
/** ์๋ฅผ ๋ค์ด, ํ์ฌ dataToSubmit.image : [์ด๋ฏธ์ง ํ์ผ, ์ด๋ฏธ์ง ํ์ผ, ์ด๋ฏธ์ง ํ์ผ...] */
for (const imageFile of dataToSubmit.image) {
formData.append("images", imageFile);
}