๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
javascript/๐Ÿ“– study

[10์ฃผ์ฐจ ์Šคํ„ฐ๋””]43์žฅ-Ajax

by HomieKim 2022. 4. 2.

Ajax

Ajax๋ž€?

  • Ajax๋ž€ Asynchronous JavaScript And Xml
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ , ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜์—ฌ ์›นํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹
  • ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” Web API์ธ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘
  • ์ด์ „์˜ ์›นํŽ˜์ด์ง€๋Š” HTML์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „์†ก ๋ฐ›์•„ ์›นํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋ง ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ ํ•จ

์ „ํ†ต์ ์ธ ๋ฐฉ์‹์˜ ๋‹จ์ 

  1. ์ด์ „ ์›นํŽ˜์ด์ง€์™€ ์ฐจ์ด๊ฐ€ ์—†์–ด ๋ณ€๊ฒฝํ•  ํ•„์š” ์—†๋Š” ๋ถ€๋ถ„๊นŒ์ง€ ํฌํ•จํ•œ ์™„์ „ํ•œ HTML์„ ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ๋งค๋ฒˆ ๋‹ค์‹œ ์ „์†ก ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ํ†ต์‹ ์ด ๋ฐœ์ƒ
  2. ํ™”๋ฉด ์ „ํ™˜์ด ์ผ์–ด๋‚˜๋ฉด์„œ ์ˆœ๊ฐ„์ ์œผ๋กœ ๊นœ๋นก์ด๋Š” ํ˜„์ƒ ๋ฐœ์ƒ
  3. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์ด ๋™๊ธฐ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ์‘๋‹ต์ด ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋‹ค์Œ ์ฒ˜๋ฆฌ๋Š” ๋ธ”๋กœํ‚น ๋œ๋‹ค.
  • ์ฆ‰, Ajax๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ์›นํŽ˜์ด์ง€์˜ ๋ณ€๊ฒฝ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ์ „์†ก ๋ฐ›์•„ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ํ•œ์ •์ ์œผ๋กœ ๋ Œ๋”๋ง ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉ

Ajax ๋ฐฉ์‹์˜ ์žฅ์ 

  1. ๋ณ€๊ฒฝํ•  ๋ถ€๋ถ„์„ ๊ฐฑ์‹ ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ์ „์†ก ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ํ†ต์‹ ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.
  2. ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„์€ ๋‹ค์‹œ ๋ Œ๋”๋ง ํ•˜์ง€ ์•Š๋Š”๋‹ค. (ํ™”๋ฉด์ด ๊นœ๋นก์ด๋Š” ํ˜„์ƒ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ)
  3. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ์ด ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญ์„ ๋ณด๋‚ธ ํ›„ ๋ธ”๋กœํ‚น ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ

JSON

  • JSON(JavaScript Object Notation)์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์˜ HTTP ํ†ต์‹ ์„ ์œ„ํ•œ ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ ํฌ๋งท

JSON ํ‘œ๊ธฐ ๋ฐฉ์‹

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํ‚ค์™€ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ˆœ์ˆ˜ํ•œ ํ…์ŠคํŠธ์ด๋‹ค.
{
  "name": "Lee",
  "age": 20,
  "alive": true,
  "hobby": ["traveling", "tennis"]
}
  • JSON์˜ ํ‚ค๋Š” ๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค.
  • ๊ฐ’์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๊ฐ™์€ ํ‘œ๊ธฐ๋ฒ•์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋”ฐ.
  • ๋‹จ, ๋ฌธ์ž์—ด์€ ๋ฐ˜๋“œ์‹œ ํฐ ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค.

JSON.stringify

  • JSON.stringify ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด๋ฅผ JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ๊ฐ์ฒด๋ฅผ ์ „์†กํ•˜๋ ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฌธ์ž์—ดํ™” ํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๋ฅผ ์ง๋ ฌํ™”(serializing)๋ผ๊ณ  ํ•œ๋‹ค.
  • JSON.stringify ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ฐฐ์—ด๋„ JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜

JSON.parse

  • JSON.parse๋ฉ”์„œ๋“œ๋Š” JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
  • ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ๋ฐ›์•„์˜จ JSON ๋ฐ์ดํ„ฐ๋Š” ๋ฌธ์ž์—ด
  • ์ด ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒดํ™” ํ•˜๋Š” ๊ฒƒ์„ ์—ญ์ง๋ ฌํ™”(deserializing) ์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ๋ฐฐ์—ด ๋ณ€ํ™˜๋œ JSON ํฌ๋งท์˜ ๊ฒฝ์šฐ, ๋ฐฐ์—ด ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋ฉฐ, ๋ฐฐ์—ด์˜ ์š”์†Œ๊ฐ€ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ ๋ฐฐ์—ด์˜ ์š”์†Œ ๊ฐ€์ง€ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

XMLHttpRequest

  • ๋ธŒ๋ผ์šฐ์ €๋Š” ์ฃผ์†Œ์ฐฝ์ด๋‚˜ form ํƒœ๊ทธ ๋˜๋Š” aํƒœ๊ทธ๋ฅผ ํ†ตํ•ด HTTP์š”์ฒญ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๋ ค๋ฉด XMLHttpRequest๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • XMLHttpRequest ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” Web API์ด๋ฏ€๋กœ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ๋™์ž‘ ํ•ฉ๋‹ˆ๋‹ค.
const xhr = new XMLHttpRequest();

XMLHttpRequest ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ

  • XMLHttpRequest๋Š” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    ์ค‘์š” ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋งŒ ์ •๋ฆฌ

ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ

  • readyState : HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒœ๋‚ด๋Š” ์ •์ˆ˜
  • status : HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜
  • statusText : HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด
  • responseType : HTTP ์‘๋‹ต ํƒ€์ž… (document, json, blob, arraybuffer...)
  • response : HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ชธ์ฒด

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ

  • onreadystatechange : readyState ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ
  • onerror : HTTP ์š”์ฒญ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ
  • onload : HTTP ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ

๋ฉ”์„œ๋“œ

  • open : HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
  • send : HTTP ์š”์ฒญ ์ „์†ก
  • abort : ์ด๋ฏธ ์ „์†ก๋œ HTTP ์š”์ฒญ ์ค‘๋‹จ
  • setRequestHeader : ํŠน์ • HTTP ์š”์ฒญ ํ—ค๋”์˜ ๊ฐ’์„ ์„ค์ •

HTTP ์š”์ฒญ ์ „์†ก

  • ๋‹ค์Œ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฆ„
  1. XMLHttpRequest.prototype.open ๋ฉ”์„œ๋“œ๋กœ HTTP ์š”์ฒญ์„ ์ดˆ๊ธฐํ™”
  2. ํ•„์š”์— ๋”ฐ๋ผ XMLHttpRequest.prototype.setRequestHeader ๋ฉ”์„œ๋“œ๋กœ ํŠน์ • HTTP ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ์„ค์ •
  3. XMLHttpRequest.prototype.send ๋ฉ”์„œ๋“œ๋กœ HTTP ์š”์ฒญ ์ „์†ก
const xhr = new XMLHttpRequest();
xhr.open('GET', '/user');
xhr.setRequestHeader('content-type', 'application/json');
xhr.send();

open ๋ฉ”์„œ๋“œ

  • open ๋ฉ”์„œ๋“œ๋Š” ์„œ๋ฒ„์— ์ „์†กํ•  HTTP์š”์ฒญ์„ ์ดˆ๊ธฐํ™” ํ•ฉ๋‹ˆ๋‹ค.
xhr.open(method, url[, async])
  • method : HTTP ์š”์ฒญ ๋ฉ”์†Œ๋“œ(GET, POST, PUT, DELETE ... )
  • url : ์š”์ฒญ์„ ์ „์†กํ•  URL
  • async : ๋น„๋™๊ธฐ ์š”์ฒญ ์—ฌ๋ถ€, ์˜ต์…˜์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์€ true

send ๋ฉ”์„œ๋“œ

  • open์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ ์š”์ฒญ์„ ์„œ๋ฒ„์— ์ „์†ก

    GET ์š”์ฒญ ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ URL์˜ ์ผ๋ถ€๋ถ„์ธ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด(query string)์œผ๋กœ ์„œ๋ฒ„์— ์ „์†ก
    POST ์š”์ฒญ์˜ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ ๋ชธ์ฒด(request body)์— ๋‹ด์•„ ์ „์†ก

  • send ๋ฉ”์„œ๋“œ๋Š” ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์ „์†กํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ด๋•Œ , JSON.stringify ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์ง๋ ฌํ™” ํ•œ ๋‹ค์Œ ์ „์†ก

setRequestHeader

  • HTTP ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ์„ค์ •

์‘๋‹ต ์ฒ˜๋ฆฌ

  • ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด XMLHttpRequest ๊ฐ์ฒด๊ฐ€ ๋ฐœ์ƒ ์‹œํ‚ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ ํ•ด์•ผํ•œ๋‹ค.
  • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด readyState๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ ํ•  ์ˆ˜ ์žˆ๋‹ค.
const xhr = new XMLHttpRequest();

// HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
// https://jsonplaceholder.typicode.com์€ Fake REST API๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค๋‹ค.
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');

xhr.send();

//  HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” readyState ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ
xhr.onreadystatechange = () => {
  // ๋งŒ์•ฝ ์„œ๋ฒ„ ์‘๋‹ต์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์•„๋ฌด๋Ÿฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  if (xhr.readyState !== XMLHttpRequest.DONE) return;

  if (xhr.status === 200) {
    console.log(JSON.parse(xhr.response));
    // {userId: 1, id: 1, title: "delectus aut autem", completed: false}
  } else {
    console.error('Error', xhr.status, xhr.statusText);
  }
};
  • readystatechange ๋Œ€์‹  load ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ ํ•ด๋„ ๋œ๋‹ค.
  • load ์ด๋ฒคํŠธ๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ
const xhr = new XMLHttpRequest();

xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');

xhr.send();

// load ์ด๋ฒคํŠธ๋Š” HTTP ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•œ๋‹ค.
xhr.onload = () => {
  if (xhr.status === 200) {
    console.log(JSON.parse(xhr.response));
    // {userId: 1, id: 1, title: "delectus aut autem", completed: false}
  } else {
    console.error('Error', xhr.status, xhr.statusText);
  }
};

๋Œ“๊ธ€