๐Ÿฆš Ajax์™€ fetch, Axios๋Š” ์–ด๋–ป๊ฒŒ ๋‹ค๋ฅผ๊นŒ?

@leedawn ยท March 13, 2024 ยท 6 min read

Ajax (Asynchronous Javascript and XML)

Ajax๋Š” ์›น ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ๋‹ค์‹œ ๋กœ๋”ฉํ•˜์ง€ ์•Š๊ณ ๋„, ์›น ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ถ„๋งŒ์„ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ Ajax๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์˜์—ญ์—์„œ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜์—ฌ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์›นํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋ถ„๋งŒ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋™์ž‘ ๋ฐฉ์‹

Ajax๋Š” XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ตํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ณ ๋„ ์ผ๋ถ€๋ถ„๋งŒ์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

const xhr = new XMLHttpRequest() // XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ

xhr.open("GET", "url-to-the-server", true) // ์š”์ฒญ ์ดˆ๊ธฐํ™” (HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ, ์š”์ฒญ์„ ๋ณด๋‚ผ ์„œ๋ฒ„์˜ url, ๋น„๋™๊ธฐ์ ์œผ๋กœ ์š”์ฒญํ•  ๊ฒƒ์ธ์ง€ boolean)
// ์‘๋‹ต ์ฒ˜๋ฆฌ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ (xhr.readyState === 4๋Š” ์š”์ฒญ ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ๋‚˜ํƒ€๋ƒ„)
xhr.onreadystatechage = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText) // ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
  }
}

xhr.send() // ์š”์ฒญ ์ „์†ก

ํ•œ๊ณ„

Ajax๋Š” XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์‚ฌ์šฉ๋ฒ•์ด ๋ณต์žกํ•˜๊ณ , ์ฝœ๋ฐฑ ์ง€์˜ฅ(callback hell)๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€์ ์ธ ๋ณ€ํ™˜ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

Fetch์˜ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

Fetch API๋Š” Promise๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์—ฌ ๋น„๋™๊ธฐ ํ†ต์‹ ์„ ๋”์šฑ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ง๊ด€์ ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. Fetch๋Š” XMLHttpRequest๋ณด๋‹ค ๋” ์œ ์—ฐํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ง์ ‘์ ์œผ๋กœ JSON์„ ์ง€์›ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ๊ฐ€ ํ›จ์”ฌ ๊ฐ„ํŽธํ•ด์กŒ๋‹ค.

Fetch API

Fetch API๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ window ๊ฐ์ฒด์— ๋‚ด์žฅ๋˜์–ด ์žˆ์œผ๋ฉฐ, Request์™€ Response ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

fetch(url, options)
  .then(response => console.log("response: ", response.json())) // JSON ๋ฐ์ดํ„ฐ๋กœ ๋ณ€ํ™˜
  .catch(error => console.log("error: ", error))

fetch๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ url, ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์˜ต์…˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›๊ณ , Promise ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋Š” API ํ˜ธ์ถœ์ด ์„ฑ๊ณตํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ์‘๋‹ต(response) ๊ฐ์ฒด๋ฅผ resolveํ•˜๊ณ , ์‹คํŒจํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ์˜ˆ์™ธ(error) ๊ฐ์ฒด๋ฅผ rejectํ•œ๋‹ค.

ํ•œ๊ณ„

Fetch API๋Š” ๋งŽ์€ ๊ฐœ์„ ์ ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ์—ฌ์ „ํžˆ ๋ช‡ ๊ฐ€์ง€ ํ•œ๊ณ„๊ฐ€ ์žˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, Fetch๋Š” ์š”์ฒญ ์‹œ๊ฐ„ ์ดˆ๊ณผ(timeouts)๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋˜ํ•œ ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ์™€ ์ผ๋ถ€ ๊ธฐ๋Šฅ(์ง„ํ–‰ ์ƒํƒœ ์ถ”์  ๋“ฑ)์— ๋Œ€ํ•œ ์ œํ•œ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

Axios์˜ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

Axios๋Š” Fetch์˜ ๋ชจ๋“  ์žฅ์ ์„ ๊ฐ€์ง€๋ฉด์„œ๋„, Fetch์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ–ˆ๋‹ค. Axios๋Š” ์š”์ฒญ ์‹œ๊ฐ„ ์ดˆ๊ณผ ์„ค์ •, ์š”์ฒญ ์ทจ์†Œ, HTTP ์ƒํƒœ ์ฝ”๋“œ์— ๋”ฐ๋ฅธ ์ž๋™ ๋ณ€ํ™˜, ์ง„ํ–‰ ์ƒํƒœ ์ถ”์  ๋“ฑ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋˜ํ•œ ๋ธŒ๋ผ์šฐ์ €๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Node.js ํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์™€ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ชจ๋‘ ์‚ฌ์šฉ๋œ๋‹ค.

Axios

Axios๋Š” HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. Axios๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ XMLHttpRequest๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, Promise ๊ธฐ๋ฐ˜์˜ API๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋ณด๋‹ค ์‰ฌ์šด ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค. ๋˜ํ•œ, ์š”์ฒญ๊ณผ ์‘๋‹ต์„ JSON ํ˜•ํƒœ๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•ด์ฃผ๊ฑฐ๋‚˜ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋“ฑ๊ณผ ์ถ”๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋ณดํ†ต ์•„๋ž˜์™€ ๊ฐ™์ด async/await์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•œ๋‹ค.

Fetch API์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ์ฐจ์ด์ ์„ ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž๋ฉด, ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • ์ž๋™ JSON ๋ณ€ํ™˜

    Axios๋Š” response๋ฅผ ์ž๋™์œผ๋กœ JSON ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค. ๋ฐ˜๋ฉด, Fetch API๋Š” response๊ฐ€ ๋„์ฐฉํ–ˆ์„ ๋•Œ, .json()์„ ํ˜ธ์ถœํ•˜์—ฌ ์ˆ˜๋™์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผํ•œ๋‹ค.

  • ์—๋Ÿฌ ์ฒ˜๋ฆฌ

    Fetch API๋Š” ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ํ•œ ์š”์ฒญ ์‹คํŒจ๋ฅผ ์•ก์…˜์ด ์‹คํŒจ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฆ‰, 404๋‚˜ 500 ๊ฐ™์€ ์„œ๋ฒ„ ์—๋Ÿฌ ์ƒํƒœ์—์„œ๋„ .then()์„ ์‹คํ–‰ํ•œ๋‹ค. ๋ฐ˜๋ฉด, Axios๋Š” 2xx ๋ฒ”์œ„ ์™ธ์˜ HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ›์œผ๋ฉด ์ž๋™์œผ๋กœ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

  • ๋ธŒ๋ผ์šฐ์ € ์ง€์›

    Fetch API๋Š” ์ผ๋ถ€ ๊ตฌํ˜• ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ˜๋ฉด, Axios๋Š” ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž‘๋™ํ•˜๋„๋ก Promise API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • timeout ์„ค์ •

    Axios๋Š” ์š”์ฒญ ํƒ€์ž„์•„์›ƒ์„ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์ด ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค. Fetch API์—์„œ๋Š” ์ด๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

์‚ฌ์šฉ๋ฒ•

const fetchData = async () => {
  try {
    const response = await axios.get("url-to-the-server")
    console.log(response.data)
  } catch (error) {
    console.error("Error! : ", error)
  }
}

๋” ์ž์„ธํ•œ ์‚ฌ์šฉ๋ฒ•์„ ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด, โš ๏ธ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธ€์„ ์ฐธ๊ณ !

@leedawn
์•ˆ๋…•ํ•˜์„ธ์š”. ์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ด์ง€ํ˜œ์ž…๋‹ˆ๋‹ค.