개발개꡴🐸 2022. 8. 15. 22:59

Ajaxλž€?

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

  • λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web API인 XMLHttpRequest 객체λ₯Ό 기반으둜 λ™μž‘
  • XMLHttpRequestλŠ” HTTP 비동기 톡신을 μœ„ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό 제곡

 

μ΄μ „μ˜ μ›ΉνŽ˜μ΄μ§€λŠ” μ™„μ „ν•œ HTML을 μ„œλ²„λ‘œλΆ€ν„° 전솑받아 μ›ΉνŽ˜μ΄μ§€ 전체λ₯Ό μ²˜μŒλΆ€ν„° λ‹€μ‹œ λ Œλ”λ§ ν•˜λŠ” λ°©μ‹μœΌλ‘œ, λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” λΆ€λΆ„κΉŒμ§€ λ‹€μ‹œ λ Œλ”λ§λ˜λŠ” 단점이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ Ajax의 λ“±μž₯은 μ΄μ „μ˜ 전톡적인 νŒ¨λŸ¬λ‹€μž„μ„ 획기적으둜 μ „ν™˜ν–ˆμŠ΅λ‹ˆλ‹€. 

 

  • μ„œλ²„λ‘œλΆ€ν„° μ›ΉνŽ˜μ΄μ§€μ˜ 변경에 ν•„μš”ν•œ λ°μ΄ν„°λ§Œ 전솑받아 λΆˆν•„μš”ν•œ 데이터 톡신 λ°œμƒ X
  • λ³€κ²½ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€λΆ„λ§Œ ν•œμ •μ μœΌλ‘œ λ Œλ”λ§ν•΄ 화면이 μˆœκ°„μ μœΌλ‘œ κΉœλ°•μ΄λŠ” ν˜„μƒμ΄ λ°œμƒ X
  • ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„μ™€μ˜ 톡신이 비동기 λ°©μ‹μœΌλ‘œ λ™μž‘ν•΄ μ„œλ²„μ—μ„œ μš”μ²­μ„ 보낸 이후 λΈ”λ‘œν‚Ήμ΄ λ°œμƒ X
  • λΈŒλΌμš°μ €μ—μ„œλ„ λ°μŠ€ν¬ν†± μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό μœ μ‚¬ν•œ λΉ λ₯Έ νΌν¬λ¨ΌμŠ€μ™€ λΆ€λ“œλŸ¬μš΄ ν™”λ©΄ μ „ν™˜μ΄ κ°€λŠ₯

JSON

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

 

JSON ν‘œκΈ° 방식

JSON은 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 객체 λ¦¬ν„°λŸ΄κ³Ό μœ μ‚¬ν•˜κ²Œ 킀와 κ°’μœΌλ‘œ κ΅¬μ„±λœ μˆœμˆ˜ν•œ ν…μŠ€νŠΈμž…λ‹ˆλ‹€.

 

{
  "name": "Lee",
  "age": 20,
  "alive": true,
  "hobby": ["traveling", "tennis"]
}
  • JSON의 ν‚€ : λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό 함
  • JSON의 κ°’ : 객체 λ¦¬ν„°λŸ΄κ³Ό 같은 ν‘œκΈ°λ²•μ„ κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 μžˆμ§€λ§Œ λ¬Έμžμ—΄μ€ λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό 함

 

JSON.stringify

직렬화(serializing)λž€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„λ‘œ 객체λ₯Ό μ „μ†‘ν•˜κΈ° μœ„ν•΄ 객체λ₯Ό λ¬Έμžμ—΄ν™”ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μ΄λ•Œ, JSON.stringify

λ©”μ„œλ“œλ₯Ό 톡해 객체λ₯Ό JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. λ˜ν•œ, 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"
  ]
}
*/


// λ°°μ—΄ λ³€ν™˜
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
  }
]
*/

 

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 }
]
*/

XMLHttpRequest

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

 

Web API인 XMLHttpRequest κ°μ²΄λŠ” HTTP μš”μ²­ 전솑과 HTTP 응닡 μˆ˜μ‹ μ„ μœ„ν•œ λ‹€μ–‘ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

XMLHttpRequest 객체 생성

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

 

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

 

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

XMLHttpRequest 객체의 λ‹€μ–‘ν•œ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œ 쀑 λŒ€ν‘œμ μΈ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°

ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹° μ„€λͺ…
readyState HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜

- UNSENT : 0
- OPENED : 1
- HEADERS_RECEIVED : 2
- LOADING : 3
- DONE : 4
status HTTP μš”μ²­μ— λŒ€ν•œ 응닡 μƒνƒœ(*HTTP μƒνƒœ μ½”λ“œ)λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜ (ex. 200)
statusText HTTP μš”μ²­μ— λŒ€ν•œ 응닡 λ©”μ‹œμ§€λ₯Ό νƒ€λ‚˜λ‚΄λŠ” λ¬Έμžμ—΄ (ex. "OK")
responseType HTTP 응닡 νƒ€μž… (ex. document, json, text, blob, arraybuffer)
response HTTP μš”μ²­μ— λŒ€ν•œ 응닡 λͺΈμ²΄. responseType에 따라 νƒ€μž…μ΄ 닀름
responseText μ„œλ²„κ°€ μ „μ†‘ν•œ HTTP μš”μ²­μ— λŒ€ν•œ 응닡 λ¬Έμžμ—΄

 

*HTTP μƒνƒœ μ½”λ“œ : https://j-su2.tistory.com/17?category=1016208 

 

[λ„€νŠΈμ›Œν¬] HTTP의 Method와 μƒνƒœμ½”λ“œ

HTTPλž€? https://j-su2.tistory.com/16 [λ„€νŠΈμ›Œν¬] HTTP와 HTTPS HTTPλž€? Hyper Text Transfer Protocol의 μ•½μžλ‘œ, μΈν„°λ„·μ—μ„œ ν…Œμ΄ν„°λ₯Ό 주고받을 수 μžˆλŠ” ν”„λ‘œν† μ½œμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 즉, μ›Ή μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ κ°„μ˜..

j-su2.tistory.com

 

이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹°

이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹° μ„€λͺ…
onreadystatechange readyState ν”„λ‘œνΌν‹° 값이 λ³€κ²½λœ 경우
onloadstart HTTP μš”μ²­μ— λŒ€ν•œ 응닡을 λ°›κΈ° μ‹œμž‘ν•œ 경우
onprogress HTTP μš”μ²­μ— λŒ€ν•œ 응닡을 λ°›λŠ” 도쀑 주기적으둜 λ°œμƒ
onabort abort λ©”μ„œλ“œμ— μ˜ν•΄ HTTP μš”μ²­μ΄ μ€‘λ‹¨λœ 경우
onerror HTTP μš”μ²­μ— μ—λŸ¬κ°€ λ°œμƒν•œ 경우
onload HTTP μš”μ²­μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œν•œ 경우
ontimeout HTTP μš”μ²­ μ‹œκ°„μ΄ μ΄ˆκ³Όν•œ 경우
onloadend HTTP μš”μ²­μ΄ μ™„λ£Œν•œ 경우. HTTP μš”μ²­μ΄ 성곡/μ‹€νŒ¨ν•˜λ©΄ λ°œμƒ

 

λ©”μ„œλ“œ

λ©”μ„œλ“œ μ„€λͺ…
open HTTP μš”μ²­ μ΄ˆκΈ°ν™”
send HTTP μš”μ²­ 전솑
abort 이미 μ „μ†‘λœ HTTP μš”μ²­ 쀑단
setRequestHeader νŠΉμ • HTTP μš”μ²­ ν—€λ”μ˜ 값을 μ„€μ •
getResponseHeader νŠΉμ • HTTP μš”μ²­ ν—€λ”μ˜ 값을 λ¬Έμžμ—΄λ‘œ λ³€ν™˜

 

정적 ν”„λ‘œνΌν‹°

정적 ν”„λ‘œνΌν‹° κ°’ μ„€λͺ…
UNSENT 0 open λ©”μ„œλ“œ 호좜 이전
OPENED 1 open λ©”μ„œλ“œ 호좜 이후
HEADERS_RECEIVED 2 send λ©”μ„œλ“œ 호좜 이후
LOADING 3 μ„œλ²„ 응닡 쀑(응닡 데이터 λ―Έμ™„μ„± μƒνƒœ)
DONE 4 μ„œλ²„ 응닡 μ™„λ£Œ

 

HTTP μš”μ²­ 전솑

HTTP μš”μ²­μ„ μ „μ†‘ν•˜λŠ” κ²½μš°λŠ” λ‹€μŒ μˆœμ„œλ₯Ό λ”°λ¦…λ‹ˆλ‹€.

  1. XMLHttpRequest.prototype.open λ©”μ„œλ“œλ‘œ HTTP μš”μ²­μ„ μ΄ˆκΈ°ν™”
  2. ν•„μš”μ— 따라 XMLHttpRequest.prototype.setRequstHeader λ©”μ„œλ“œλ‘œ νŠΉμ • 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 μš”μ²­μ„ μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

 

xhr.open(method, url[, async]);
λ§€κ°œλ³€μˆ˜ μ„€λͺ…
method HTTP μš”μ²­ λ©”μ„œλ“œ("GET", "POST", "PUT", "DELETE" λ“±)
url HTTP μš”μ²­μ„ 전솑할 URL
async 비동기 μš”μ²­ μ—¬λΆ€. μ˜΅μ…˜μœΌλ‘œ 기본값은 true이며, 비동기 λ°©μ‹μœΌλ‘œ λ™μž‘

 

HTTP μš”μ²­ λ©”μ„œλ“œλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ—μ„œ μš”μ²­μ˜ μ’…λ₯˜μ™€ λͺ©μ (λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ ν–‰μœ„)을 μ•Œλ¦¬λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

μ•„λž˜μ™€ 같이 주둜 5κ°€μ§€ μš”μ²­ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ CRUDλ₯Ό κ΅¬ν˜„ν•©λ‹ˆλ‹€.

 

HTTP μš”μ²­ λ©”μ†Œλ“œ μ’…λ₯˜ λͺ©μ  νŽ˜μ΄λ‘œλ“œ
GET index/retrieve λͺ¨λ“ /νŠΉμ • λ¦¬μ†Œλ“œ 취득 X
POST create λ¦¬μ†ŒμŠ€ 생성 O
PUT replace λ¦¬μ†ŒμŠ€μ˜ 전체 ꡐ체 O
PATCH modify λ¦¬μ†ŒμŠ€μ˜ 일뢀 μˆ˜μ • O
DELETE delete λͺ¨λ“ /νŠΉμ • λ¦¬μ†ŒμŠ€ μ‚­μ œ X

 

XMLHttpRequest.prototype.send

send λ©”μ„œλ“œλŠ” open λ©”μ„œλ“œλ‘œ μ΄ˆκΈ°ν™”λœ HTTP μš”μ²­μ„ μ„œλ²„μ— μ „μ†‘ν•©λ‹ˆλ‹€. 기본적으둜 μ„œλ²„λ‘œ μ „μ†‘ν•˜λŠ” λ°μ΄ν„°λŠ” GET, POST μš”μ²­ λ©”μ„œλ“œμ— 따라 전솑 방식에 차이가 μžˆμŠ΅λ‹ˆλ‹€.

 

GET μš”μ²­ λ©”μ„œλ“œ

  • 데이터λ₯Ό URL의 일뢀뢄인 쿼리 λ¬Έμžμ—΄(query string)둜 μ„œλ²„μ— 전솑
  • 데이터(νŽ˜μ΄λ‘œλ“œ, payload)둜 μ „λ‹¬ν•œ μΈμˆ˜λŠ” λ¬΄μ‹œλ˜κ³  μš”μ²­ λͺΈμ²΄(request body)λŠ” null둜 μ„€μ •

POST μš”μ²­ λ©”μ„œλ“œ

  • 데이터(νŽ˜μ΄λ‘œλ“œ, payload)λ₯Ό μš”μ²­ λͺΈμ²΄(request body)에 λ‹΄μ•„ 전솑
  • request body에 λ‹΄μ•„ 전솑할 데이터λ₯Ό 인수둜 전달할 수 있음
  • νŽ˜μ΄λ‘œλ“œκ°€ 객체인 경우 λ°˜λ“œμ‹œ JSON.stringigy λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ§λ ¬ν™”ν•œ λ‹€μŒ 전달해야 함
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));

 

XMLHttpRequest.prototype.setRequstHeader

νŠΉμ • HTTP μš”μ²­μ˜ 헀더 값을 μ„€μ •ν•˜λŠ” setRequstHeader λ©”μ„œλ“œλŠ” λ°˜λ“œμ‹œ open λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 이후에 ν˜ΈμΆœν•΄μ•Όν•©λ‹ˆλ‹€.

setRequstHeader λ©”μ„œλ“œλ‘œ 주둜 HTTP μš”μ²­ 헀더인 Content-typeκ³Ό Acceptλ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

 

Content-type은 μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ 전솑할 λ°μ΄ν„°μ˜ MIME νƒ€μž…μ˜ 정보λ₯Ό ν‘œν˜„ν•©λ‹ˆλ‹€.

 

MIME νƒ€μž… μ„œλΈŒ νƒ€μž…
text text/plain, text/html, text/css, text/javascipt
application application/json, application/x-www-form-urlencode
multipart multipart/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둜 μ§€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ§Œμ•½ Accept 헀더λ₯Ό μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ send λ©”μ„œλ“œκ°€ 호좜될 λ•Œ Accept 헀더가 */*으둜 μ „μ†‘λ©λ‹ˆλ‹€.

 

// μ„œλ²„κ°€ 응닡할 λ°μ΄ν„°μ˜ MIME νƒ€μž… μ§€μ •: json
xhr.setRequestHeader('accept', 'application/json');

 

HTTP 응닡 처리

μ„œλ²„κ°€ μ „μ†‘ν•œ 응닡을 μ²˜λ¦¬ν•˜λ €λ©΄ XMLHttpRequest 객체가 λ°œμƒμ‹œν‚€λŠ” 이벀트λ₯Ό μΊμΉ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 

XMLHttpRequest 객체의 이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹° μ€‘μ—μ„œ HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” readyState ν”„λ‘œνΌν‹° 값이 λ³€κ²½λœ 경우 λ°œμƒν•˜λŠ” readystatechange 이벀트λ₯Ό μΊμΉ˜ν•˜μ—¬ λ‹€μŒκ³Ό 같이 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);
  }
};
  1. μ–Έμ œ 응닡이 ν΄λΌμ΄μ–ΈνŠΈμ— λ„λ‹¬ν• μ§€λŠ” μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” readyState ν”„λ‘œνΌν‹°κ°€ 변경될 λ•Œλ§ˆλ‹€ DONE인지 ν™•μΈν•˜μ—¬ μ„œλ²„μ˜ 응닡이 μ™„λ£Œλ˜μ—ˆλŠ”μ§€ 확인
  2. μ„œλ²„μ˜ 응닡이 μ™„λ£Œλ˜λ©΄ HTTP μƒνƒœ μ½”λ“œκ°€ 200인지 ν™•μΈν•˜μ—¬ 정상 μ²˜λ¦¬μ™€ μ—λŸ¬ 처리λ₯Ό ꡬ뢄
  3. 응닡이 μ •μƒμ μœΌλ‘œ λ„μ°©ν–ˆλ‹€λ©΄ μš”μ²­μ— λŒ€ν•œ 응닡 λͺΈμ²΄λ₯Ό λ‚˜νƒ€λ‚΄λŠ” xhr.responceμ—μ„œ μ„œλ²„κ°€ μ „μ†‘ν•œ 데이터λ₯Ό 취득
  4. λ§Œμ•½ xhr.statusκ°€ 200이 μ•„λ‹ˆλ©΄ μ—λŸ¬κ°€ λ°œμƒν•œ μƒνƒœμ΄λ―€λ‘œ ν•„μš”ν•œ μ—λŸ¬ 처리λ₯Ό 함

μ΄λŸ¬ν•œ readystatechange 이벀트 λŒ€μ‹  HTTP μš”μ²­μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλœ 경우 λ°œμƒν•˜λŠ” load 이벀트λ₯Ό μΊμΉ˜ν•΄λ„ λ©λ‹ˆλ‹€.

 

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

[좜처] λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive

https://wikibook.co.kr/mjs/

 

λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive: μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κΈ°λ³Έ κ°œλ…κ³Ό λ™μž‘ 원리

269개의 κ·Έλ¦Όκ³Ό 원리λ₯Ό νŒŒν—€μΉ˜λŠ” μ„€λͺ…μœΌλ‘œ ‘μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κΈ°λ³Έ κ°œλ…κ³Ό λ™μž‘ 원리’λ₯Ό μ΄ν•΄ν•˜μž! μ›ΉνŽ˜μ΄μ§€μ˜ λ‹¨μˆœν•œ 보쑰 κΈ°λŠ₯을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ μ œν•œμ μΈ μš©λ„λ‘œ νƒœμ–΄λ‚œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 과도

wikibook.co.kr