๐Ÿ’ป My Work/๐Ÿ”ฅ React

[React/JS] ์„œ๋ฒ„์— ํŒŒ์ผ ๊ฐ์ฒด(File Object)/์ด๋ฏธ์ง€ ํŒŒ์ผ ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ ๊ฐœ ๋ณด๋‚ด๊ธฐ - FormData

Jaeseo Kim 2022. 11. 2. 09:32

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๋ฅผ ์ฝ˜์†”์— ์ฐ์–ด๋ณผ๊นŒ์š”??

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);
  }