Ajax ๐Ÿ˜ฎ

c_yjยท2022๋…„ 7์›” 19์ผ
0

DeepDive

๋ชฉ๋ก ๋ณด๊ธฐ
37/42
post-thumbnail

Ajax๋ž€ โ“

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

์ด์ „์˜ ์›นํŽ˜์ด์ง€๋Š” html ํƒœ๊ทธ๋กœ ์‹œ์ž‘ํ•ด์„œ html ํƒœ๊ทธ๋กœ ๋๋‚˜๋Š” ์™„์ „ํ•œ HTML์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „์†ก๋ฐ›์•„ ์›นํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ™”๋ฉด์ด ์ „ํ™˜๋˜๋ฉด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด HTML์„ ์ „์†ก๋ฐ›์•„ ์›นํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋งํ–ˆ๋‹ค.

์ „ํ†ต ์ ์ธ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ์ ์ด ์žˆ๋‹ค

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

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

Ajax๋Š” ์ „ํ†ต์ ์ธ ๋ฐฉ์‹๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์ด ์žˆ๋‹ค.

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

JSON โ“

JSON์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์˜ HTTP ํ†ต์‹ ์„ ์œ„ํ•œ ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ ํฌ๋งท์ด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ์ข…์†๋˜์ง€ ์•Š๋Š” ์–ธ์–ด ๋…๋ฆฝํ˜• ๋ฐ์ดํ„ฐ ํฌ๋งท์œผ๋กœ, ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

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

JSON์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํ‚ค์™€ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋œ ์ˆ˜๋ˆ—ํ•œ ํ…์ŠคํŠธ๋‹ค.

{
  "name" : "Lee",
  "age" : 20,
  "alive" : true,
  "hobby" : ["traveling", "tennis"]
}

JSON์˜ ํ‚ค๋Š” ๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค. ๊ฐ’์€ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด๊ณผ ๊ฐ™์€ ํ‘œ๊ธฐ๋ฒ•์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ž์—ด์€ ๋ฐ˜๋“œ์‹œ ํฐ๋”ฐ์˜ดํ‘œ๋กœ ๋ฌถ์–ด์•ผ ํ•œ๋‹ค.

JSON.stringify ๐ŸŸฃ

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

const obj = {
  name: 'Lee',
  age: 20,
  alive: true,
  hobby: ['traveling', 'tennis']
};

// ๊ฐ์ฒด๋ฅผ JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
const json = JSON.stringify(obj);
console.log(typeof json, json);
// string {"name":"Lee","age":20,"alive":true,"hobby":["traveling","tennis"]}

// ๊ฐ์ฒด๋ฅผ JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด์„œ ๋“ค์—ฌ์“ฐ๊ธฐ ํ•œ๋‹ค.
const prettyJson = JSON.stringify(obj, null, 2);
console.log(typeof prettyJson, prettyJson);

/*
string {
  "name": "Lee",
  "age": 20,
  "alive": true,
  "hobby": [
    "traveling",
    "tennis"
  ]
}
*/

// replacer ํ•จ์ˆ˜. ๊ฐ’์˜ ํƒ€์ž…์ด Number์ด๋ฉด ํ•„ํ„ฐ๋ง๋˜์–ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค.
function filter(key, value) {
  // undefined: ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์Œ
  return typeof value === 'number' ? undefined : value;
}

// JSON.stringify ๋ฉ”์„œ๋“œ์— ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ replacer ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.
const strFilteredObject = JSON.stringify(obj, filter, 2);
console.log(typeof strFilteredObject, strFilteredObject);

/*
string {
  "name": "Lee",
  "alive": true,
  "hobby": [
    "traveling",
    "tennis"
  ]
}
*/

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

JSON.parse ๐ŸŸฃ

JSON.parse ๋ฉ”์„œ๋“œ๋Š” JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „์„ฑ๋œ JSON ๋ฐ์ดํ„ฐ๋Š” ๋ฌธ์ž์—ด์ด๋‹ค. ์ด ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด์„ ๊ฐ์ฒดํ™”ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์ด๋ฅผ ์—ญ์ง๋ ฌํ™”๋ผ ํ•œ๋‹ค.

const obj = {
  name: 'Lee',
  age: 20,alive: true,
  hobby: ['traveling', 'tennis']
};

// ๊ฐ์ฒด๋ฅผ JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
const json = JSON.stringify(obj);

// JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด์„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
// object {name: "Lee", age: 20.alive: true.hobby:["traveling","tenis"]

๋ฐฐ์—ด์ด JSON ํฌ๋งท์˜ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ JSON.parse๋Š” ๋ฌธ์ž์—ด์„ ๋ฐฐ์—ด ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ๋ฐฐ์—ด์˜ ์š”์†Œ๊ฐ€ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ ๋ฐฐ์—ด์˜ ์š”์†Œ๊นŒ์ง€ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

XMLHttpRequest โ“

๋ธŒ๋ผ์šฐ์ €๋Š” ์ฃผ์†Œ์ฐฝ์ด๋‚˜ HTML์˜ form ํƒœ๊ทธ ๋˜๋Š” a ํƒœ๊ทธ๋ฅผ ํ†ตํ•ด HTTP ์š”์ฒญ ์ „์†ก ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ ์ œ๊ณตํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๋ ค๋ฉด XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. Web API์ธ XMLHttpRequest ๊ฐ์ฒด๋Š” HTTP ์š”์ฒญ ์ „์†ก๊ณผ HTTP ์‘๋‹ต ์ˆ˜์‹ ์„ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ์™€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ ๐ŸŸ 

XMLHttpRequest ๊ฐ์ฒด๋Š” XMLHttpRequest ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑํ•œ๋‹ค. XMLHttpRequest ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” Web API์ด๋ฏ€๋กœ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค.

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

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

XMLHttpRequest ๊ฐ์ฒด๋Š” ๋‹ค์–‘ํ•œ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

XMLHttpRequest ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ

ํ”„๋กœํ† ํƒ€์ž… ํ”„๋กœํผํ‹ฐ์„ค๋ช…
readyStateHTTP ์š”์ฒญ์œผ๋กœ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜. ๋‹ค์Œ๊ณผ ๊ฐ™์€ XMLHttpRequest์˜ ์ •์  ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ–๋Š”๋‹ค.
UNSENT:0
OPENED:1
HEADERS_RECEIVED: 2
LOADING: 3
DONE:4
statueTextHTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ฉ”์‹œ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด
์˜ˆ) "OK"
responseTypeHTTP ์‘๋‹ต ํƒ€์ž„
์˜ˆ) document, jsion, text, blob, arraybuffer
responseHTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ชธ์ฒด, responseType์— ๋”ฐ๋ผ ํƒ€์ž…์ด ๋‹ค๋ฅด๋‹ค
responseText์„œ๋ฒ„๊ฐ€ ์ „์†กํ•œ HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ฌธ์ž์—ด

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

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ์„ค๋ช…
onReadystatechangereadyState ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ
onloadstartHTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ฐ›๊ธฐ ์‹œ์ž‘ํ•œ ๊ฒฝ์šฐ
onprogressHTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋ฐ›๋Š” ๋„์ค‘ ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐœ์ƒ
onabortabort ๋ฉ”์„œ๋“œ์— ์˜ํ•ด HTTP ์š”์ฒญ์ด ์ค‘๋‹จ๋œ ๊ฒฝ์šฐ
onerrorHTTP ์š”์ฒญ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ
onloadHTTP ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒํ•œ ๊ฒฝ์šฐ
ontimeoutHTTP ์š”์ฒญ ์‹œ๊ฐ„์ด ์ดˆ๊ณผํ•œ ๊ฒฝ์šฐ
onloadendHTTP ์š”์ฒญ์— ์™„๋ฃŒํ•œ ๊ฒฝ์šฐ, HTTP ์š”์ฒญ์ด ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจํ•˜๋ฉด ๋ฐœ์ƒ

XMLHttpRequest ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ์„ค๋ช…
openHTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
endHTTP ์š”์ฒญ ์ „์†ก
abort์ด๋ฏธ ์ „์†ก๋œ HTTP ์š”์ฒญ ์ค‘๋‹จ
setRequestHeaderํŠน์ • HTTP ์š”์ฒญ ํ—ค๋”์˜ ๊ฐ’์„ ์„ค์ •
getResponseHeaderํŠน์ • HTTP ์š”์ฒญ ํ—ค๋”์˜ ๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜

XMLHttpRequest ๊ฐ์ฒด์˜ ์ •์  ํ”„๋กœํผํ‹ฐ

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ๊ฐ’์„ค๋ช…
UNSENT0open ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ด์ „
OPENED1open ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ดํ›„
HEADERS_RECEIVED2send ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ดํ›„
OPENED3์„œ๋ฒ„ ์‘๋‹ต ์ค‘(์‘๋‹ต ๋ฐ์ดํ„ฐ ๋ฏธ์™„์„ฑ ์ƒํƒœ)
OPENED4์„œ๋ฒ„ ์‘๋‹ต ์™„๋ฃŒ

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

HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค.

  1. XMLHttpRequest.prototype.open ๋ฉ”์„œ๋“œ๋กœ HTTP ์š”์ฒญ์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
  2. ํ•„์š”์— ๋”ฐ๋ผ XMLHttpRequest.prototye.setRequestHeader ๋ฉ”์„œ๋“œ๋กœ ํŠน์ • HTTP ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.
  3. XMLHttpRequest.prototype.send ๋ฉ”์„œ๋“œ๋กœ HTTP ์š”์ฒญ์„ ์ „์†กํ•œ๋‹ค
// XMLHttpRequest ๊ฐ์ฒด ์ƒ์„ฑ
const xhr = new XMLHttpRequest();

// HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
xhr.open('GET', '/users');

// HTTP ์š”์ฒญ ํ—ค๋” ์„ค์ •
// ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž… ์ง€์ •: json
xhr.setRequestHeader('content-type', 'application/json');

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

XMLHttpRequest.prototype.open
open ๋ฉ”์„œ๋“œ๋Š” ์„œ๋ฒ„์— ์ „์†กํ•  HTTP ์š”์ฒญ์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. open ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

xhr.open(method, url[, async])

๋งค๊ฐœ๋ณ€์ˆ˜์„ค๋ช…
methodHTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ("GET", "POST", "PUT", "DELETE" ๋“ฑ
urlHTTP ์š”์ฒญ์„ ์ „์†กํ•  URL
async๋น„๋™๊ธฐ ์š”์ฒญ ์—ฌ๋ถ€, ์˜ต์…˜์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์€ true์ด๋ฉฐ, ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ์š”์ฒญ์˜ ์ข…๋ฅ˜์™€ ๋ชฉ์ ์„ ์•Œ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ฃผ๋กœ 5๊ฐ€์ง€ ์š”์ฒญ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ CRUD๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ์ข…๋ฅ˜๋ชฉ์ ํŽ˜์ด๋กœ๋“œ
GETindex/retrieve๋ชจ๋“ /ํŠน์ • ๋ฆฌ์†Œ์Šค ์ทจ๋“X
POSTcreate๋ฆฌ์†Œ์Šค ์ƒ์„ฑO
PUTreplace๋ฆฌ์†Œ์Šค์˜ ์ „์ฒด ๊ต์ฒดO
PATCHmodify๋ฆฌ์†Œ์Šค์˜ ์ผ๋ถ€ ์ˆ˜์ •O
DELETEdelete๋ชจ๋“ /ํŠน์ • ๋ฆฌ์†Œ์Šค ์‚ญ์ œX

XMLHttpRequest.prototype.send
send ๋ฉ”์„œ๋“œ๋Š” open ๋ฉ”์„œ๋“œ๋กœ ์ดˆ๊ธฐํ™”๋œ HTTP ์š”์ฒญ์„ ์„œ๋ฒ„์— ์ „์†กํ•œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” GET, POST ์š”์ฒญ ๋ฉ”์„œ๋“œ์— ๋”ฐ๋ผ ์ „์†ก ๋ฐฉ์‹์— ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

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

    send ๋ฉ”์„œ๋“œ์—๋Š” ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์ „์†กํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ํŽ˜์ด๋กœ๋“œ๊ฐ€ ๊ฐ์ฒด์ธ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ JSON.stringify ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง๋ ฌํ™”ํ•œ ๋‹ค์Œ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.
xhr.send(JSON.stringify({id: 1, content: 'HTML', completed: false}));

HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๊ฐ€ GET์ธ ๊ฒฝ์šฐ send ๋ฉ”์„œ๋“œ์— ํŽ˜์ด๋กœ๋“œ๋กœ ์ „๋‹ฌํ•œ ์ธ์ˆ˜๋Š” ๋ฌด์‹œ๋˜๊ณ  ์š”์ฒญ ๋ชธ์ฒด๋Š” null๋กœ ์„ค์ •๋œ๋‹ค.

XMLHttpRequest.prototype.setRequestHeader
setRequestHeader ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • HTTP ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค. setRequestHeader ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜๋“œ์‹œ open ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ์ดํ›„์— ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” HTTP ์š”์ฒญ ํ—ค๋”์ธ Content-type๊ณผ Accept์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์ž.
Content-type์€ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์ „์†กํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž…์˜ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค. ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” MIME ํƒ€์ž…์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

MIME ํƒ€์ž…์„œ๋ธŒํƒ€์ž…
texttext/plain, text/html, text/css, text/javascript
applicatioapplication/json, application/x-www-form-urlencode
multipartmultipart/formed-data

๋‹ค์Œ์€ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MIME ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ์˜ˆ๋‹ค.

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

// HTTP ์š”์ฒญ ์ดˆ๊ธฐํ™”
xhr.open('POST', '/users');

// HTTP ์š”์ฒญ ํ—ค๋” ์„ค์ •
// ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž… ์ง€์ •: json
xhr.setRequestHeader('content-type', 'application/json');

// HTTP ์š”์ฒญ ์ „์†ก
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));

HTTP ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญํ•  ๋–„ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž…์„ Accept๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์Œ์€ ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ์˜ˆ๋‹ค.

// ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•  ๋ฐ์ดํ„ฐ์˜ MIME ํƒ€์ž… ์ง€์ •: json
xhr.setRequestHeader('accept', 'application/json');

HTTP ์‘๋‹ต ์ฒ˜๋ฆฌ ๐ŸŸ 

์„œ๋ฒ„๊ฐ€ ์ „์†กํ•œ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด XMLHttpRequest ๊ฐ์ฒด๊ฐ€ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ํ•ด์•ผ ํ•œ๋‹ค. XMLHttpRequest ๊ฐ์ฒด๋Š” onreadystatechange, onload, onerror ๊ฐ™์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š”๋‹ค. ์ด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ ์ค‘์—์„œ HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” readyState ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜๋Š” readystatechange ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด HTTP ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

XMLHttpRequest ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” Web API์ด๋ฏ€๋กœ ๋‹ค์Œ ์˜ˆ์ œ๋Š” ๋ฐ˜๋“œ์‹œ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

์ฐธ๊ณ ๋กœ HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์œผ๋ ค๋ฉด ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์—์„œ๋Š” JSONPlaceholder์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐ€์ƒ REST API๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

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

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

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

// readystatechange ์ด๋ฒคํŠธ๋Š” HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” readyState ํ”„๋กœํผํ‹ฐ๊ฐ€
// ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฐœ์ƒํ•œ๋‹ค.
xhr.onreadystatechange = () => {
  // readyState ํ”„๋กœํผํ‹ฐ๋Š” HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  // readyState ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 4(XMLHttpRequest.DONE)๊ฐ€ ์•„๋‹ˆ๋ฉด ์„œ๋ฒ„ ์‘๋‹ต์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋‹ค.
  // ๋งŒ์•ฝ ์„œ๋ฒ„ ์‘๋‹ต์ด ์•„์ง ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์•„๋ฌด๋Ÿฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  if (xhr.readyState !== XMLHttpRequest.DONE) return;
  
  // status ํ”„๋กœํผํ‹ฐ๋Š” ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  // status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ์ด๊ณ 
  // status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ๋‹ค.
  // ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ๋ผ๋ฉด response ํ”„๋กœํผํ‹ฐ์— ์„œ๋ฒ„์˜ ์‘๋‹ต ๊ฒฐ๊ณผ๊ฐ€ ๋‹ด๊ฒจ ์žˆ๋‹ค.
  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);
  }
};

send ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด HTTP ์š”์ฒญ์„ ์„œ๋ฒ„์— ์ „์†กํ•˜๋ฉด ์„œ๋ฒ„๋Š” ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์–ธ์ œ ์‘๋‹ต์ด ํด๋ผ์ด์–ธํŠธ์— ๋„๋‹ฌํ• ์ง€๋Š” ์•Œ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ readystateonchange ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. readystatechange ์ด๋ฒคํŠธ๋Š” HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” readyState ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋ฐœ์ƒํ•œ๋‹ค.

onreadystatechange ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” HTTP ์š”์ฒญ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” xhr.readyState๊ฐ€ XMLHttpRequest.DONE์ธ์ง€ ํ™•์ธํ•˜์—ฌ ์„œ๋ฒ„์˜ ์‘๋‹ต์ด ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

์„œ๋ฒ„์˜ ์‘๋‹ต์ด ์™„๋ฃŒ๋˜๋ฉด HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ์ƒํƒœ(HTTP ์ƒํƒœ ์ฝ”๋“œ)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” xhr.status๊ฐ€ 200์ธ์ง€ ํ™•์ธํ•˜์—ฌ ์ •์ƒ ์ฒ˜๋ฆฌ์™€ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค. HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์ด ์ •์ƒ์ ์œผ๋กœ ๋„์ฐฉํ–ˆ๋‹ค๋ฉด ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต ๋ชธ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” xhr.response์—์„œ ์„œ๋ฒ„๊ฐ€ ์ „์†กํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ทจ๋“ํ•œ๋‹ค. ๋งŒ์•ฝ xhr.status๊ฐ€ 200์ด ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ์ด๋ฏ€๋กœ ํ•„์š”ํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

readystatechange ์ด๋ฒคํŠธ ๋Œ€์‹  load ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ํ•ด๋„ ์ข‹๋‹ค. load ์ด๋ฒคํŠธ๋Š” HTTP ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ load ์ด๋ฒคํŠธ๋ฅผ ์บ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ xhr.readyState๊ฐ€ XMLHttpRequest.DONE์ธ์ง€ ํ™•์ธํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.


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

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

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

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

  // status ํ”„๋กœํผํ‹ฐ๋Š” ์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
  // status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ์ด๊ณ 
  // status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํƒœ๋‹ค.
  // ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ๋ผ๋ฉด response ํ”„๋กœํผํ‹ฐ์— ์„œ๋ฒ„์˜ ์‘๋‹ต ๊ฒฐ๊ณผ๊ฐ€ ๋‹ด๊ฒจ ์žˆ๋‹ค.
  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);
  }
};
profile
FrontEnd Developer

0๊ฐœ์˜ ๋Œ“๊ธ€