Skip to content

Commit

Permalink
Merge pull request #1286 from narinn-star/narinn-star
Browse files Browse the repository at this point in the history
43μž₯ Ajax - μ΄λ‚˜λ¦°
  • Loading branch information
Ryan-Dia authored Jan 26, 2024
2 parents e76db9d + ec5beba commit 61c360d
Showing 1 changed file with 256 additions and 0 deletions.
256 changes: 256 additions & 0 deletions docs/43_Ajax/μ΄λ‚˜λ¦°.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# 🎯 43 Ajax

[43.1 Ajaxλž€?](#1-ajaxλž€)
[43.2 JSON](#2-json)
[43.3 XMLHttpRequest](#3-xmlhttprequest)

## 1. Ajaxλž€?

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

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

μ„œλ²„λ‘œλΆ€ν„° μ›ΉνŽ˜μ΄μ§€μ˜ 변경에 ν•„μš”ν•œ λ°μ΄ν„°λ§Œ 비동기 λ°©μ‹μœΌλ‘œ 전솑받아 μ›ΉνŽ˜μ΄μ§€λ₯Ό λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” 뢀뢄은 λ‹€μ‹œ λ Œλ”λ§ν•˜μ§€ μ•Šκ³ , λ³€κ²½ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€λΆ„λ§Œ λ Œλ”λ§ν•˜λŠ” 방식이 κ°€λŠ₯ν•΄μ‘Œλ‹€. 이λ₯Ό 톡해 λΈŒλΌμš°μ €μ—μ„œλ„ λ°μŠ€ν¬ν†± μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό μœ μ‚¬ν•œ λΉ λ₯Έ νΌν¬λ¨ΌμŠ€μ™€ λΆ€λ“œλŸ¬μš΄ ν™”λ©΄ μ „ν™˜μ΄ κ°€λŠ₯ν•΄μ‘Œλ‹€.

✨ Ajax의 μž₯점 (전톡 방식과 비ꡐ)

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

## 2. JSON

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

## 2.1 JSON ν‘œκΈ° 방식

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

ν‚€λŠ” λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό ν•˜λ©°, 값은 객체 λ¦¬ν„°λŸ΄κ³Ό 같은 ν‘œκΈ°λ²•μ„ κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
λ¬Έμžμ—΄μ€ λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό ν•œλ‹€.

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

### 2.2 JSON.stringify

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

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

const json = JSON.stringify(obj);
console.log(typeof json, json);
// string {"name":"Lee","age":20,"alive":true,"hobby":["traveling","tennis"]}

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

### 2.3 JSON.parse

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

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

const json = JSON.stringify(obj);

const parsed = JSON.parse(json);
console.log(typeof parsed, parsed);
// object {"name":"Lee","age":20,"alive":true,"hobby":["traveling","tennis"]}
```

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

## 3. XMLHttpRequest

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

### 3.1 XMLHttpRequest 객체 생성

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

```javascript
const xhr = new XMLHttpRequest();
```

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

λŒ€ν‘œμ μΈ ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

- XMLHttpRequest 객체의 ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°

- readyState
- status
- statusText
- responseType
- response
- HTTP μš”μ²­μ— λŒ€ν•œ 응닡 λͺΈμ²΄ (response body), responseType에 따라 νƒ€μž…μ΄ 닀름
- responseText

- XMLHttpRequest 객체의 이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹°

- onreadystatechange
- onloadstart
- onprogress
- onabort
- abort λ©”μ„œλ“œμ— μ˜ν•΄ HTTP μš”μ²­μ΄ μ€‘λ‹¨λœ 경우
- onerror
- onload
- ontimeout
- onloadend

- XMLHttpRequest 객체의 λ©”μ„œλ“œ

- open
- send
- abort
- setRequestHeader
- νŠΉμ • HTTP μš”μ²­ ν—€λ”μ˜ 값을 μ„€μ •
- getRequestHeader
- νŠΉμ • HTTP μš”μ²­ ν—€λ”μ˜ 값을 λ¬Έμžμ—΄λ‘œ λ°˜ν™˜

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

### 3.3 HTTP μš”μ²­ 전솑

1. XMLHttpRequest.prototype.open λ©”μ„œλ“œλ‘œ HTTP μš”μ²­μ„ μ΄ˆκΈ°ν™”
2. ν•„μš”μ— 따라 XMLHttpRequest.prototype.setRequestHeader λ©”μ„œλ“œλ‘œ νŠΉμ • HTTP μš”μ²­μ˜ 헀더 값을 μ„€μ •
3. XMLHttpRequest.prototype.send λ©”μ„œλ“œλ‘œ HTTP μš”μ²­μ„ 전솑

```javascript
const xhr = new XMLHttpRequest();

xhr.open('GET', '/users');

xhr.setRequestHeader('content-type', 'application/json');

xhr.send();
```

✨ **XMLHttpRequest.prototype.open**

open λ©”μ„œλ“œλŠ” μ„œλ²„μ— 전솑할 HTTP μš”μ²­μ„ μ΄ˆκΈ°ν™”ν•œλ‹€.
ν˜ΈμΆœμ€ μ•„λž˜μ™€ 같이 ν•œλ‹€.

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

- method : HTTP μš”μ²­ λ©”μ„œλ“œ
- GET, POST, PUT, PATCH, DELETE
- url : HTTP μš”μ²­μ„ 전솑할 URL
- async : 비동기 μš”μ²­ μ—¬λΆ€. μ˜΅μ…˜μœΌλ‘œ 기본값은 true, 비동기 λ°©μ‹μœΌλ‘œ λ™μž‘ν•œλ‹€.

✨ **XMLHttpRequest.prototype.send**

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

- GET μš”μ²­ λ©”μ„œλ“œμΌ 경우 데이터λ₯Ό URL의 일뢀뢄인 쿼리 λ¬Έμžμ—΄λ‘œ μ„œλ²„μ— μ „μ†‘ν•œλ‹€. (query string)
- POST μš”μ²­ λ©”μ„œλ“œμΌ 경우 데이터(νŽ˜μ΄λ‘œλ“œ, payload)λ₯Ό μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ μ „μ†‘ν•œλ‹€. (request body)

send λ©”μ„œλ“œμ—λŠ” μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ 전솑할 데이터λ₯Ό 인수둜 전달할 수 μžˆλ‹€. νŽ˜μ΄λ‘œλ“œκ°€ 객체인 경우 λ°˜λ“œμ‹œ JSON.stringify λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄ μ§λ ¬ν™”ν•œ λ‹€μŒ 전달해야 ν•œλ‹€.

```javascript
xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));
```

βœ”οΈ **HTTP μš”μ²­ λ©”μ„œλ“œκ°€ GET인 경우 send λ©”μ„œλ“œμ— νŽ˜μ΄λ‘œλ“œλ‘œ μ „λ‹¬ν•œ μΈμˆ˜λŠ” λ¬΄μ‹œλ˜κ³  μš”μ²­ λͺΈμ²΄λŠ” null둜 μ„€μ •λœλ‹€.**

✨ **XMLHttpRequest.prototype.setRequestHeader**

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

자주 μ‚¬μš©ν•˜λŠ” HTTP μš”μ²­ 헀더인 Content-typeκ³Ό Accept에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μž.

- Content-type
μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ 전솑할 λ°μ΄ν„°μ˜ MIME νƒ€μž…μ˜ 정보λ₯Ό ν‘œν˜„ν•œλ‹€.
- MIME νƒ€μž…
text : text/plain, text/html, text/css, text/javascript
application : application/json, application/x-www-form-urlencode
multipart : multipart/formed-data

```javascript
const xhr = new XMLHttpRequest();

xhr.open('POST', '/users');

xhr.setRequestHeader('content-type', 'application/json');

xhr.send(JSON.stringify({ id: 1, content: 'HTML', completed: false }));
```

- Accept
HTTP ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ— μš”μ²­ν•  λ•Œ 응닡할 λ°μ΄ν„°μ˜ MIME νƒ€μž…μ„ Accept둜 지정할 수 μžˆλ‹€.
Accept 헀더λ₯Ό μ„€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ send λ©”μ„œλ“œκ°€ 호좜될 λ•Œ Accept 헀더가 */*으둜 μ „μ†‘λœλ‹€.

```javascript
xhr.setRequestHeader('accept', 'application/json');
```

### 3.4 HTTP 응닡 처리

- send λ©”μ„œλ“œλ₯Ό 톡해 HTTP μš”μ²­μ„ μ„œλ²„μ— μ „μ†‘ν•˜λ©΄ μ„œλ²„λŠ” 응닡을 λ°˜ν™˜ν•œλ‹€.
- readystatechange 이벀트λ₯Ό 톡해 HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό ν™•μΈν•œλ‹€.
- μ„œλ²„μ˜ 응닡이 μ™„λ£Œλ˜λ©΄ 응닡 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” statusκ°€ 200인지 ν™•μΈν•˜κ³  정상 μ²˜λ¦¬μ™€ μ—λŸ¬ 처리λ₯Ό κ΅¬λΆ„ν•œλ‹€.
- μ •μƒμ μœΌλ‘œ λ„μ°©ν–ˆλ‹€λ©΄ μ„œλ²„κ°€ μ „μ†‘ν•œ 데이터λ₯Ό responseμ—μ„œ μ·¨λ“ν•˜λ©° μ—λŸ¬κ°€ λ°œμƒν–ˆλ‹€λ©΄ ν•„μš”ν•œ μ—λŸ¬ 처리λ₯Ό ν•œλ‹€.

0 comments on commit 61c360d

Please sign in to comment.