πŸ“Œ 43μž₯ Ajax

경이·2022λ…„ 8μ›” 3일
0
post-thumbnail

πŸš€ 43.1 Ajaxλž€?

Ajax(Asynchronous JavaScript and XML)λž€ μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ λΈŒλΌμš°μ €κ°€ μ„œλ²„μ—κ²Œ 비동기 λ°©μ‹μœΌλ‘œ 데이터λ₯Ό μš”μ²­ν•˜κ³ , μ„œλ²„κ°€ μ‘λ‹΅ν•œ 데이터λ₯Ό μˆ˜μ‹ ν•˜μ—¬ μ›ΉνŽ˜μ΄μ§€λ₯Ό λ™μ μœΌλ‘œ κ°±μ‹ ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 방식을 λ§ν•œλ‹€. AjaxλŠ” λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web API인 XMLHttpRequest 객체λ₯Ό 기반으둜 λ™μž‘ν•œλ‹€. XMLHttpRequestλŠ” HTTP 비동기 톡신을 μœ„ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό μ œκ³΅ν•œλ‹€.

Ajax의 μž₯점을 λ„μ‹ν™”ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

  1. λ³€κ²½ν•  뢀뢄을 κ°±μ‹ ν•˜λŠ” 데 ν•„μš”ν•œ λ°μ΄ν„°λ§Œ μ„œλ²„λ‘œλΆ€ν„° 전솑받기 λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ 데이터 톡신이 λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
  2. λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” 뢀뢄은 λ‹€μ‹œ λ Œλ”λ§ν•˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ 화면이 μˆœκ°„μ μœΌλ‘œ κΉœλ°•μ΄λŠ” ν˜„μƒμ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
  3. ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„μ™€μ˜ 톡신이 비동기 λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— μ„œλ²„μ—κ²Œ μš”μ²­μ„ 보낸 이후 λΈ”λ‘œν‚Ήμ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

πŸš€ 43.2 JSON

JSON(JavaScript Object Notation)은 ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ HTTP 톡신을 μœ„ν•œ ν…μŠ€νŠΈ 데이터 포맷이닀. μžλ°”μŠ€ν¬λ¦½νŠΈμ— μ’…μ†λ˜μ§€ μ•ŠλŠ” μ–Έμ–΄ λ…λ¦½ν˜• 데이터 포맷으둜 λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

βœ” 43.2.1 JSON ν‘œκΈ° 방식

JSON은 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 객체 λ¦¬ν„°λŸ΄κ³Ό μœ μ‚¬ν•˜κ²Œ 킀와 κ°’μœΌλ‘œ κ΅¬μ„±λœ μˆœμˆ˜ν•œ ν…μŠ€νŠΈλ‹€. JSON의 ν‚€λŠ” λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό ν•˜λ©° 값은 객체 λ¦¬ν„°λŸ΄κ³Ό 같은 ν‘œκΈ°λ²•μ„ κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ λ¬Έμžμ—΄μ€ λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό ν•œλ‹€.

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

βœ” 43.2.2 JSON.stringify

JSON.stringify λ©”μ„œλ“œλŠ” 객체λ₯Ό JSON 포멧의 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€. ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„λ‘œ 객체λ₯Ό μ „μ†‘ν•˜λ €λ©΄ 객체λ₯Ό λ¬Έμžμ—΄ν™”ν•΄μ•Ό ν•˜λŠ”λ‹€. 이λ₯Ό 직렬화(serializing)라 ν•œλ‹€.

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 포맷의 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜ν•œλ‹€.

const todos = [
  { id: 1, content: 'HTML', completed: false },
  { id: 2, content: 'CSS', completed: true },
  { id: 3, content: 'Javascript', completed: false }
];

// 배열을 JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•œλ‹€.
const json = JSON.stringify(todos, null, 2);
console.log(typeof json, json);
/*
string [
  {
    "id": 1,
    "content": "HTML",
    "completed": false
  },
  {
    "id": 2,
    "content": "CSS",
    "completed": true
  },
  {
    "id": 3,
    "content": "Javascript",
    "completed": false
  }
]
*/

βœ” 43.2.3 JSON.parse

JSON.parse λ©”μ„œλ“œλŠ” JSON 포맷의 λ¬Έμžμ—΄μ„ 객체둜 λ³€ν™˜ν•œλ‹€. μ„œλ²„λ‘œλΆ€ν„° ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ „μ†‘λœ JSON λ°μ΄ν„°λŠ” λ¬Έμžμ—΄μ΄λ‹€. 이 λ¬Έμžμ—΄μ„ κ°μ²΄λ‘œμ„œ μ‚¬μš©ν•˜λ €λ©΄ JSON 포맷의 λ¬Έμžμ—΄μ„ 객체화 ν•΄μ•Ό ν•˜λŠ”λ° 이λ₯Ό 역직렬화(deserializing)라 ν•œλ‹€.

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", "tennis"]}

배열이 JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜λ˜μ–΄ μžˆλŠ” 경우 JSON.parseλŠ” λ¬Έμžμ—΄μ„ λ°°μ—΄ 객체둜 λ³€ν™˜ν•œλ‹€. λ°°μ—΄μ˜ μš”μ†Œκ°€ 객체인 경우 λ°°μ—΄μ˜ μš”μ†ŒκΉŒμ§€ 객체둜 λ³€ν™˜ν•œλ‹€.

const todos = [
  { id: 1, content: 'HTML', completed: false },
  { id: 2, content: 'CSS', completed: true },
  { id: 3, content: 'Javascript', completed: false }
];

// 배열을 JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•œλ‹€.
const json = JSON.stringify(todos);

// JSON 포맷의 λ¬Έμžμ—΄μ„ λ°°μ—΄λ‘œ λ³€ν™˜ν•œλ‹€. λ°°μ—΄μ˜ μš”μ†ŒκΉŒμ§€ 객체둜 λ³€ν™˜λœλ‹€.
const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
/*
 object [
  { id: 1, content: 'HTML', completed: false },
  { id: 2, content: 'CSS', completed: true },
  { id: 3, content: 'Javascript', completed: false }
]
*/

πŸš€ 43.3 XMLHttpRequest

λΈŒλΌμš°μ €λŠ” μ£Όμ†Œμ°½μ΄λ‚˜ HTML의 form νƒœκ·Έ λ˜λŠ” a νƒœκ·Έλ₯Ό 톡해 HTTP μš”μ²­ 전솑 κΈ°λŠ₯을 κΈ°λ³Έ μ œκ³΅ν•œλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ HTTP μš”μ²­μ„ μ „μ†‘ν•˜λ €λ©΄ XMLHttpRequest 객체λ₯Ό μ‚¬μš©ν•œλ‹€. Web API인 XMLHttpRequest κ°μ²΄λŠ” HTTP μš”μ²­ 전솑과 HTTP 응닡 μˆ˜μ‹ μ„ μœ„ν•œ λ‹€μ–‘ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό μ œκ³΅ν•œλ‹€.

βœ” 43.3.1 XMLHttpRequest 객체 생성

XMLHttpRequest κ°μ²΄λŠ” XMLHttpRequest μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒμ„±ν•œλ‹€. XMLHttpRequest κ°μ²΄λŠ” λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web API μ΄λ―€λ‘œ λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œλ§Œ μ •μƒμ μœΌλ‘œ μ‹€ν–‰λœλ‹€.

// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();

βœ” 43.3.2 XMLHttpRequest 객체의 ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œ

XMLHttpRequest κ°μ²΄λŠ” λ‹€μŒκ³Ό 같은 λ‹€μ–‘ν•œ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•œλ‹€.

  • XMLHttpRequest 객체의 ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°
    ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°μ„€λͺ…
    readyStateHTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜
    λ‹€μŒκ³Ό 같은 XMLHttpRequest의 정적 ν”„λ‘œνΌν‹°λ₯Ό κ°’μœΌλ‘œ κ°–λŠ”λ‹€.
    β–ͺ UNSENT: 0
    β–ͺ OPENED: 1
    β–ͺ HEADERS_RECEIVED: 2
    β–ͺ LOADING: 3
    β–ͺ DONE: 4
    statusHTTP μš”μ²­μ— λŒ€ν•œ 응닡 μƒνƒœ(HTTP μƒνƒœ μ½”λ“œ)λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜
    ex) 200
    statusTextHTTP μš”μ²­μ— λŒ€ν•œ 응닡 λ©”μ‹œμ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄ex) "OK"
    responseTypeHTTP 응닡 νƒ€μž…ex) document, json, 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 λ©”μ„œλ“œ 호좜 이후
    LOADING3μ„œλ²„ 응닡 쀑(응닡 데이터 λ―Έμ™„μ„± μƒνƒœ)
    DONE4μ„œλ²„ 응닡 μ™„λ£Œ

βœ” 43.3.3 HTTP μš”μ²­ 전솑

HTTP μš”μ²­ 전솑은 λ‹€μŒ μˆœμ„œλ₯Ό λ”°λ₯Έλ‹€.

  1. XMLHttpRequest.prototype.open λ©”μ„œλ“œλ‘œ HTTP μš”μ²­μ„ μ΄ˆκΈ°ν™”ν•œλ‹€.
  2. ν•„μš”μ— 따라 XMLHttpRequest.prototype.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가지 μš”μ²­ λ©”μ„œλ“œ(GET, POST, PUT, PATCH, DELETE λ“±)λ₯Ό μ‚¬μš©ν•˜μ—¬ 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 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 이후에 ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€. Content-typeκ³Ό AcceptλŠ” 자주 μ‚¬μš©ν•˜λŠ” HTTP μš”μ²­ 헀더이닀. Content-type은 μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ 전솑할 λ°μ΄ν„°μ˜ MIME νƒ€μž…μ˜ 정보λ₯Ό ν‘œν˜„ν•œλ‹€. 자주 μ‚¬μš©λ˜λŠ” MIME νƒ€μž…μ€ λ‹€μŒκ³Ό κ°™λ‹€.
    MIME νƒ€μž…μ„œλΈŒνƒ€μž…
    texttext/plain, text/html, text/css, text/javascript
    applicationapplication/json, application/x-www-form-urlencode
    multipartmultipart/formed-data
    // 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');
    λ§Œμ•½ Accept 헀더λ₯Ό μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ sendκ°€ 호좜될 λ•Œ Accept 헀더가 / 으둜 μ „μ†‘λœλ‹€.

βœ” 43.3.4 HTTP 응닡 처리

μ„œλ²„κ°€ μ „μ†‘ν•œ 응닡을 μ²˜λ¦¬ν•˜λ €λ©΄ XMLHttpRequest 객체가 λ°œμƒμ‹œν‚€λŠ” 이벀트λ₯Ό μΊμΉ˜ν•΄μ•Ό ν•œλ‹€. XMLHttpRequest κ°μ²΄λŠ” onreadystatechange, onload, onerror 같은 이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹°λ₯Ό κ°–λŠ”λ‹€. 이 이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹° μ€‘μ—μ„œ HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” readyState ν”„λ‘œνΌν‹° 값이 λ³€κ²½λœ 경우 λ°œμƒν•˜λŠ” readystatechange 이벀트λ₯Ό μΊμΉ˜ν•˜μ—¬ λ‹€μŒκ³Ό 같이 HTTP 응닡을 μ²˜λ¦¬ν•  수 μžˆλ‹€.

XMLHttpRequest κ°μ²΄λŠ” λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web APIμ΄λ―€λ‘œ λ‹€μŒ μ˜ˆμ œλŠ” λ°˜λ“œμ‹œ λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œ μ‹€ν–‰ν•΄μ•Ό ν•˜λ©° 참고둜 HTTP μš”μ²­μ„ μ „μ†‘ν•˜κ³  응닡을 λ°›μœΌλ €λ©΄ μ„œλ²„κ°€ ν•„μš”ν•˜λ‹€.

// 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 μš”μ²­μ„ μ„œλ²„μ— μ „μ†‘ν•˜λ©΄ μ„œλ²„λŠ” 응닡을 λ°˜ν™˜ν•˜μ§€λ§Œ μ–Έμ œ 응닡이 ν΄λΌμ΄μ–ΈνŠΈμ— λ„λ‹¬ν• μ§€λŠ” μ•Œ 수 μ—†λ‹€. λ”°λΌμ„œ readystatechange 이벀트λ₯Ό 톡해 HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό 확인해야 ν•œλ‹€. readystatechange μ΄λ²€νŠΈλŠ” HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” readyState ν”„λ‘œνΌν‹°κ°€ 변경될 λ•Œλ§ˆλ‹€ λ°œμƒν•œλ‹€.

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

// load μ΄λ²€νŠΈλŠ” HTTP μš”μ²­μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλœ 경우 λ°œμƒν•œλ‹€.
xhr.onload = () => {
  // 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
μ΄μ‚¬μ€‘μž…λ‹ˆλ‹€!🌟https://velog.io/@devkyoung2

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보