From c53de5a8d6d64b9b505e131c1e9f3c112269814a Mon Sep 17 00:00:00 2001 From: sehyun Date: Fri, 26 Jan 2024 10:10:29 +0900 Subject: [PATCH] =?UTF-8?q?docs:=2043=EC=9E=A5=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\202\230\354\204\270\355\230\204.md" | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 "docs/43_Ajax/\353\202\230\354\204\270\355\230\204.md" diff --git "a/docs/43_Ajax/\353\202\230\354\204\270\355\230\204.md" "b/docs/43_Ajax/\353\202\230\354\204\270\355\230\204.md" new file mode 100644 index 00000000..cf17c396 --- /dev/null +++ "b/docs/43_Ajax/\353\202\230\354\204\270\355\230\204.md" @@ -0,0 +1,138 @@ +## 43μž₯ Ajax + +### πŸ“ 43.1: Ajaxλž€? + +**Ajax**: μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•΄ λΆ€λΌμš°μ €κ°€ μ„œλ²„μ—κ²Œ 비동기 λ°©μ‹μœΌλ‘œ 데이터λ₯Ό μš”μ²­ν•˜κ³ , μ„œλ²„κ°€ μ‘λ‹΅ν•œ 데이터λ₯Ό μˆ˜μ‹ ν•΄ μ›ΉνŽ˜μ΄μ§€λ₯Ό λ™μ μœΌλ‘œ κ°±μ‹ ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 방식 + +AjaxλŠ” λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web API인 `XMLHttpRequest` 객체λ₯Ό 기반으둜 λ™μž‘ν•˜λ©°, 이 κ°μ²΄λŠ” HTTP 비동기 톡신을 μœ„ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό μ œκ³΅ν•œλ‹€. +μ΄μ „μ˜ μ›ΉνŽ˜μ΄μ§€λŠ” μ™„μ „ν•œ HTML을 μ„œλ²„λ‘œλΆ€ν„° 전솑받아 μ›ΉνŽ˜μ΄μ§€ 전체λ₯Ό λ¦¬λ Œλ”λ§ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ™μž‘ν–ˆλŠ”λ°, 이런 전톡적인 방식은 λ‹€μŒκ³Ό 같은 단점을 κ°–λŠ”λ‹€. + +- 이전 μ›ΉνŽ˜μ΄μ§€κ°€ 차이가 μ—†μ–΄μ„œ λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” λΆ€λΆ„κΉŒμ§€ ν¬ν•¨ν•œ μ™„μ „ν•œ HTML을 μ„œλ²„λ‘œλΆ€ν„° 맀번 λ‹€μ‹œ 전솑받기 λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ 데이터 톡신이 λ°œμƒν•œλ‹€. +- λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” λΆ€λΆ„κΉŒμ§€ μ²˜μŒλΆ€ν„° λ‹€μ‹œ λ Œλ”λ§ν•œλ‹€. 이둜 인해 ν™”λ©΄ μ „ν™˜μ΄ μΌμ–΄λ‚˜λ©΄ 화면이 μˆœκ°„μ μœΌλ‘œ κΉœλ°•μ΄λŠ” ν˜„μƒμ΄ λ°œμƒν•œλ‹€. +- ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„μ™€μ˜ 톡신이 동기 λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— μ„œλ²„λ‘œλΆ€ν„° 응닡이 μžˆμ„ λ•ŒκΉŒμ§€ λ‹€μŒ μ²˜λ¦¬λŠ” λΈ”λ‘œν‚Ήλœλ‹€. + +Ajax의 λ“±μž₯으둜 인해 μ„œλ²„λ‘œλΆ€ν„° 변경에 ν•„μš”ν•œ λ°μ΄ν„°λ§Œ 비동기 λ°©μ‹μœΌλ‘œ 전솑받아 μ›ΉνŽ˜μ΄μ§€λ₯Ό λ³€κ²½ν•  ν•„μš”κ°€ μ—†λŠ” 뢀뢄은 λ‹€μ‹œ λ Œλ”λ§ν•˜μ§€ μ•Šκ³ , λ³€κ²½ν•  ν•„μš”κ°€ μžˆλŠ” λΆ€λΆ„λ§Œ ν•œμ •μ μœΌλ‘œ λ Œλ”λ§ν•˜λŠ” 방식이 κ°€λŠ₯ν•΄μ‘Œλ‹€. + +### πŸ“ 43.2: JSON + +**JSON**: ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ HTTP 톡신을 μœ„ν•œ ν…μŠ€νŠΈ 데이터 포맷 (μžλ°”μŠ€ν¬λ¦½νŠΈμ— μ’…μ†λ˜μ§€ μ•ŠλŠ” μ–Έμ–΄ λ…λ¦½ν˜• 포맷으둜, λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ μ‚¬μš© κ°€λŠ₯) + +#### JSON ν‘œκΈ° 방식 + +μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 객체 λ¦¬ν„°λŸ΄κ³Ό μœ μ‚¬ν•˜κ²Œ 킀와 κ°’μœΌλ‘œ κ΅¬μ„±λœ μˆœμˆ˜ν•œ ν…μŠ€νŠΈλ‹€. +JSON의 ν‚€λŠ” λ°˜λ“œμ‹œ ν°λ”°μ˜΄ν‘œλ‘œ λ¬Άμ–΄μ•Ό ν•œλ‹€. (값은 μƒκ΄€μ—†μŒ) + +```json +{ + "name": "Lee", + "age": 20, + "alive": true, + "hobby": ["traveling", "tennis"] +} +``` + +#### `JSON.stringify` + +`JSON.stringify` λ©”μ„œλ“œλŠ” 객체λ₯Ό JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•œλ‹€. +ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„λ‘œ 객체λ₯Ό μ „μ†‘ν•˜λ €λ©΄ 객체λ₯Ό μ΄λ ‡κ²Œ λ¬Έμžμ—΄ν™”ν•΄μ•Ό ν•˜λŠ”λ°, 이λ₯Ό 직렬화(serializing)라 ν•œλ‹€. +객체뿐만 μ•„λ‹ˆλΌ 배열도 JSON 포맷의 λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•œλ‹€. + +#### `JSON.parse` + +JSON 포맷의 λ¬Έμžμ—΄μ„ 객체둜 λ³€ν™˜ν•œλ‹€. +μ„œλ²„λ‘œλΆ€ν„° ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ „μ†‘λœ JSON λ°μ΄ν„°λŠ” λ¬Έμžμ—΄μΈλ°, 이 λ¬Έμžμ—΄μ„ κ°μ²΄λ‘œμ„œ μ‚¬μš©ν•˜λ €λ©΄ μ΄λ ‡κ²Œ 객체화해야 ν•œλ‹€. (deserializing) + +### πŸ“ 43.3: `XMLHttpRequest` + +μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•΄ HTTP μš”μ²­μ„ μ „μ†‘ν•˜λ €λ©΄ `XMLHttpRequest` 객체λ₯Ό μ‚¬μš©ν•œλ‹€. +Web API인 이 κ°μ²΄λŠ” HTTP μš”μ²­κ³Ό HTTP 응닡 μˆ˜μ‹ μ„ μœ„ν•œ λ‹€μ–‘ν•œ λ©”μ„œλ“œμ™€ ν”„λ‘œνΌν‹°λ₯Ό μ œκ³΅ν•œλ‹€. + +#### `XMLHttpRequest` 객체 생성 + +`XMLHttpRequest` μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ μƒμ„±ν•œλ‹€. +이 κ°μ²΄λŠ” λΈŒλΌμš°μ €μ—μ„œ μ œκ³΅ν•˜λŠ” Web APIμ΄λ―€λ‘œ λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œλ§Œ μ •μƒμ μœΌλ‘œ μ‹€ν–‰λœλ‹€. + +```javascript +const xhr = new XMLHttpRequest(); +``` + +#### `XMLHttpRequest` 객체의 ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œ + +**ν”„λ‘œν† νƒ€μž… ν”„λ‘œνΌν‹°** + +- `readyState`: HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜ +- `status`: HTTP μš”μ²­μ— λŒ€ν•œ 응닡 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” μ •μˆ˜ +- `statusText`: HTTP μš”μ²­μ— λŒ€ν•œ 응닡 λ©”μ‹œμ§€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” λ¬Έμžμ—΄ +- `responseType`: HTTP 응닡 νƒ€μž… +- `response`: HTTP μš”μ²­μ— λŒ€ν•œ 응닡 body + +**이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹°** + +- `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 μš”μ²­μ„ μ „μ†‘ν•œλ‹€. + +```javascript +const xhr = new XMLHttpRequest(); + +xhr.open('GET', '/users'); + +xhr.setRequestHeader('content-type', 'application/json'); + +xhr.send(); +``` + +#### HTTP 응닡 처리 + +μ„œλ²„κ°€ μ „μ†‘ν•œ 응닡을 μ²˜λ¦¬ν•˜λ €λ©΄ `XMLHttpRequest` 객체가 λ°œμƒμ‹œν‚€λŠ” 이벀트λ₯Ό μΊμΉ˜ν•΄μ•Ό ν•œλ‹€. +이 객체가 κ°–λŠ” 이벀트 ν•Έλ“€λŸ¬ ν”„λ‘œνΌν‹° μ€‘μ—μ„œ HTTP μš”μ²­μ˜ ν˜„μž¬ μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” `readyState` ν”„λ‘œνΌν‹° 값이 λ³€κ²½λœ 경우 λ°œμƒν•˜λŠ” `readystatechange` 이벀트λ₯Ό μΊμΉ˜ν•΄ λ‹€μŒκ³Ό 같이 HTTP 응닡을 μ²˜λ¦¬ν•  수 μžˆλ‹€. + +```javascript +const xhr = new XMLHttpRequest(); + +xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1'); + +xhr.send(); + +xhr.onreadystatechange = () => { + if (xhr.readyState !== XMLHttpRequest.DONE) return; + + if (xhr.status === 200) { + console.log(JSON.parse(xhr.response)); + } else { + console.error('Error', xhr.status, xhr.statusText); + } +}; +``` + +`readystatechange` λŒ€μ‹  HTTP μš”μ²­μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλœ 경우 λ°œμƒν•˜λŠ” `load` 이벀트λ₯Ό μΊμΉ˜ν•΄λ„ μ’‹λ‹€. +ν•΄λ‹Ή 이벀트λ₯Ό μΊμΉ˜ν•˜λŠ” 경우 `xhr.readyState`κ°€ `XMLHttpRequest.DONE`인지 확인할 ν•„μš”κ°€ μ—†λ‹€. + +```javascript +const xhr = new XMLHttpRequest(); + +xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1'); + +xhr.send(); + +xhr.onload = () => { + if (xhr.status === 200) { + console.log(JSON.parse(xhr.response)); + } else { + console.error('Error', xhr.status, xhr.statusText); + } +}; +```