-
자바스크립트 웹 개발 기본기코드잇 부스트 2024. 7. 13. 16:11
웹 기초 다지기
- fetch 함수와 response 객체
- fetch 함수는 Promise 객체를 반환
- 이 객체의 then 메소드로, '리스폰스가 왔을 때 실행할 콜백'을 등록할 수 있음.
- 이렇게 등록된 콜백들은 then 메소드로 등록한 순서대로 실행되고, 이때 이전 콜백의 리턴값을 이후 콜백이 넘겨받아서 사용할 수 있음
- 처음 넘어온 response는 각종 부가 정보들과, 실제 내용을 함께 갖고 있는 하나의 객체(object)가 넘어옴, 따라서 reponse 객체의 text라는 메소드를 호출해서 내용을 가져와야 함.
- 개발자 도구란?프론트 엔드 개발자에게 유용하다.
- https://developers.google.com/web/tools/chrome-devtools 위 링크에서 자세한 내용을 볼 수 있다.
- 웹, url이란?url(Uniform Resourse Locater)은 host, path, query로 이루어지고, query는 &로 연결되어 있다.스킴, 호스트, 패스, 쿼리로 나뉜다.
- **<https://www.codeitshoppingmall.com/bags/new?size=m**>
- 웹은 서버에 요청을 보내 정보를 보여준다.
- URL로 리퀘스트 보내기위 방법으로 보낼 수 있다.
- fetch('<https://workey.codeit.kr/ratings>') .then((response) => response.text()) .then((result) => { console.log(result); });
Web API 배우기
- Json이란?
- JSON의 기본 자료형: Number, String, Boolean, Array, Object, null
- JSON(JavaScript Object Notation) 자바스크립트 언어 데이터 포맷
- 자바스크립트 객체 표기법과 JSON 문법의 차이
- JSON에서는 각 프로퍼티의 이름을 반드시 큰따옴표(")로 감싸줘야 한다
- JSON에서는 값이 문자열인 경우 큰따옴표(")를 사용해야 한다
- JSON에서는 undefined, NaN, Infinity 을 표현할 수 없다
- JSON에서는 주석을 달 수 없다.
- { "name":"Michael Kim", "height":180, "weight":70, "hobbies":["Basketball", "Listening to music"] }
- JSON 데이터를 객체로 변환하기
- JSON.parse() 메소드로 string 타입의 JSON 데이터를 자바스크립트 배열로 변환할 수 있다
- 메소드의 의미
- GET Read(데이터 조회)
- POST Create(데이터 생성)
- PUT Update(데이터 수정)
- DELETE Delete(데이터 삭제)
- Request의 Head와 Body
- Request는 Head와 Body로 이루어져 있다
- Head 리퀘스트에 관한 여러 가지 부가 정보들이 들어있는 부분
- Body 실제 데이터를 담는 부분
- Request Header request head 안에 존재하는 하나하나의 key-value 쌍
- HTTP headers 참조
- Request는 Head와 Body로 이루어져 있다
- Pseudo-header 앞에는 콜론이 붙어있다
- POST request 보내기JSON.stringify()를 이용해 객체를 JSON string으로 변환해야 한다.
- // 새로운 직원 정보 추가 const newMember = { name: 'jeris', email: 'jeris@email.kr', department: 'engineering', }; fetch('<https://learn.codeit.kr/api/members>', { method: 'POST', body: JSON.stringify(newMember), }) .then((response) => response.text()) .then((result) => { console.log(result)});
- PUT request, DELETE request 보내기PUT 리퀘스트DELETE 리퀘스트
- // id=6인 직원 정보 삭제 fetch('<https://learn.codeit.kr/api/members/6>', { method: 'DELETE', }) .then((response) => response.text()) .then((result) => { console.log(result)});
- // id=6인 직원 정보 수정 const member = { name: 'jeris', email: 'jeris@email.kr', department: 'marketing', }; fetch('<https://learn.codeit.kr/api/members/6>', { method: 'PUT', body: JSON.stringify(member), }) .then((response) => response.text()) .then((result) => { console.log(result)});
- 모범적인 Web API, REST API
- Web API(Application Programming Interface):
- URL로 리퀘스트를 보냈을 때, 무슨 처리가 수행되고 어떤 리스폰스가 오는지에 관해 미리 정해진 규격을 말한다.
- REST API:
- REST architecture를 준수하여 Web API를 설계하게 하는 가이드라인이다.
- REST(Representational State Transfer) architecture:
- Roy Fielding이 제시한 웹이 갖추어야 할 이상적인 구조이다.
- REST architecture가 되기 위한 조건
- Client-Server Client-Server 구조를 통해 양측의 관심사를 분리해야 한다
- Stateless 즉, 매 리퀘스트는 독립적이고, Client가 보낸 리퀘스트에 관해서 Server는 어떤 context도 저장하지 않는다.
- Cache Cache를 활용해서 네트워크 비용을 절감해야 한다. Server는 response에, Client가 response를 재활용해도 되는지 여부(Cacheable)를 담아서 보내야 한다.
- Uniform Interface Client가 Server와 통신하는 인터페이스가 준수해야될 규칙이다. 총 4개가 있다.
- identification of resources resource를 URI로 식별할 수 있어야 한다
- manipulation of resources through representations Client와 Server는 둘 다 resource를 직접적으로 다루는 게 아니라 resource의 representations를 다뤄야 한다
- self-descriptive messages request와 response 모두 그 자체에 있는 정보만으로 모든 것을 해석할 수 있어야 한다
- hypermedia as the engine of application state response에는 현재 상태에서 다른 상태로 이전할 수 있는 링크를 포함하고 있어야 한다
- Layered System Cline와 Sㅜ erver 사이에는 proxy, gateway와 같은 중간 매개 요소를 두고, 보안, 로드 밸런싱 등을 수행할 수 있어야 한다. 이를 통해 Client와 Server 사이에는 hierarchical layers가 형성된다
- Code on Demand Client는 받아서 바로 실행할 수 있는 applet이나 script 파일을 Server로부터 받을 수 있어야 한다. 이 조건은 Optional이므로 REST architecture가 되기 위해 반드시 만족될 필요는 없다
- RESTful service 이런 REST API를 사용하는 웹 서비스
- identification of resources에 관해서 특히 중요한 규칙 2가지
- URL은 resource를 나타내기 위해서만 사용하고, resource handling은 method로 해야 한다
- Document는 단수 명사로, Collection은 복수 명사로 표시한다
- document 하나의 객체로 표현할 수 있는 resource (file)
- collection Documents를 담을 수 있는 resource (directory)
- Web API(Application Programming Interface):
- JSON 데이터 다루기 종합
- Serialization 자바스크립트 객체를 JSON string으로 변환
- Deserialization JSON string을 자바스크립트 객체로 변환
- response.json() JSON string을 parsing한 결과를 담은 promise 객체를 리턴하는 메소드
- Status CodeStatus Code란 Request를 받은 server가 그 작업 결과를 나타내기 위해서 Response head에 넣는 숫자이다.
- 00번대: server가 client에게 정보성 응답(Informational response)를 줄 때 사용된다
- 100 Continue Client가 server에게 계속 request를 보내도 괜찮은지 물어봤을 때, 계속 request를 보내도 괜찮다고 알려주는 상태 코드
- 101 Switching Protocols Client가 protocol을 바꾸자는 request를 허락한다고 알려주는 코드
- 200번대: request가 성공 처리되었음을 의미한다
- 200 OK request가 성공적으로 처리되었음을 포괄적으로 의미하는 상태 코드
- 201 Created request의 내용대로 resource가 잘 생성되었음을 의미하는 상태 코드
- 202 Accepted request의 내용이 일단은 잘 접수되었음을 의미하는 상태 코드
- 300번대: client의 request가 아직 처리되지 않았고, request 처리를 원하면 client 측의 추가적인 작업이 필요함을 의미한다
- 301 Moved Permanently resource의 위치가 바뀌었음을 나타내는 상태 코드
- 302 Found resource의 위치가 일시적으로 바뀌었음을 나타내는 상태 코드
- 301, 302같은 상태 코드가 있는 response의 head에는 Location이라는 헤더도 일반적으로 포함되어 있다
- 대부분의 브라우저는 GET request의 response로 이런 상태 코드를 받았을 때, 헤드에 포함된 Location 값으로 redirection 동작을 수행합니다
- 304 Not Modified response로 받았던 resource가 변경되지 않았으므로 client에게 caching된 resource를 사용하도록 권하는 상태 코드
- HTTP caching 참조
- 400번대: request를 보내는 client 쪽에 문제가 있음을 의미한다
- 400 Bad Request request에 문제가 있을 때 나타내는 상태 코드
- 401 Unauthorized 아직 신원이 확인되지 않은(unauthenticated) user로부터 온 request를 처리할 수 없다는 뜻을 의미하는 상태 코드
- 403 Forbidden user의 신원은 확인되었지만 해당 resource에 접근 권한이 없어서 처리할 수 없다는 뜻을 의미하는 상태 코드
- 404 Not Found 해당 URL이 나타내는 resource를 찾을 수 없다는 뜻을 의미하는 상태 코드
- 405 Method Not Allowed 해당 resource에 대해서 요구한 처리는 허용되지 않는다는 뜻을 의미하는 상태 코드
- 413 Payload Too Large 현재 request의 body에 들어있는 data의 size가 지나치게 커서 server가 거부한다는 뜻을 의미하는 상태 코드
- 429 Too Many Requests 일정 시간동안 client가 지나치게 많은 request를 보냈다는 뜻을 의미하는 상태 코드
- 500번대: Server 쪽의 문제로 인해 request를 정상적으로 처리할 수 없음을 의미한다
- 500 Internal Server Error 현재 알 수 없는 server 내의 error로 인해 request를 처리할 수 없다는 뜻을 의미하는 상태 코드
- 503 Service Unavailable 현재 server 점검 중이거나, traffic 폭주 등으로 인해 service를 제공할 수 없다는 뜻을 의미하는 상태 코드
- 그 외 상태 코드 참고
- 00번대: server가 client에게 정보성 응답(Informational response)를 줄 때 사용된다
- Response도 Head와 Body로 이루어져 있다
- Content-Type이란
- 주 타입이 text인 경우(텍스트)
- 일반 텍스트 : text/plain
- CSS 코드 : text/css
- HTML 코드 : text/html
- JavaScript 코드 : text/javascript ...
- 주 타입이 image인 경우(이미지)
- image/bmp : bmp 이미지
- image/gif : gif 이미지
- image/png : png 이미지 ...
- 주 타입이 audio인 경우(오디오)
- audio/mp4 : mp4 오디오
- audio/ogg : ogg 오디오 ...
- 주 타입이 video인 경우(비디오)
- video/mp4 : mp4 비디오
- video/H264 : H264 비디오 ...
- 주 타입이 text인 경우(텍스트)
- 현재 리퀘스트 또는 리스폰스의 바디에 들어 있는 데이터가 어떤 타입인지를 나타낸다.
- 알아두면 좋은 Content-type들
이런 JSON 데이터를 XML로는 이렇게 나타낼 수 있다.그외:<?xml version="1.0" encoding="UTF-8" ?> <person> <name>Michael Kim</name> <height>180</height> <weight>70</weight> <hobbies> <value>Basketball</value> <value>Listening to music</value> </hobbies> </person>
이 데이터를 application/x-www-form-urlencoded 타입으로 나타내보면(2) multipart/form-data 타입 등{ "id": 6, "name": "Jason", "age": 34, "department": "engineering" }
- id=6&name=Jason&age=34&department=engineering
- (1) application/x-www-form-urlencoded 타입
- XML을 쓸 때는 보통 스키마(Schema)라는 별도의 문서를 함께 사용한다. 이 스키마에는 각 조직, 기관 등에서 XML로 데이터를 나타낼 때, 어떤 태그들을 사용할 수 있고, 각 태그의 의미는 무엇이며, 특정 태그는 어떤 타입의 값을 가질 수 있는지 등의 정보가 담겨있다.
- { "name":"Michael Kim", "height":180, "weight":70, "hobbies":[ "Basketball", "Listening to music" ] }
- 그 밖에 알아야 할 내용들웹 페이지에서 사용자가 정보를 요청했을 때 전체 내용을 새로고침하지 않고 리퀘스트를 보내고 정보를 받아와 사용자에게 보여줄 수 있는 기능이다.GET, POST, PUT, DELETE 이외의 메소드들:Put과 다르게 새데이터로 기존 데이터의 일부를 수정할 때 사용함.GET과 동일 하지만 body를 가져오지 않음, 받아오는 데이터가 대용량인지 확인할 때 유용.HTTP, HTTPS 이외에도, FTP, SSH, TCP, UDP, IP, Ethernet 등 정말 다양한 종류의 프로토콜이 있다.
- 웹 이외의 통신:
- HEAD:
- PATCH:
- 지금은 fetch나 axios에서 이를 사용할 수 있다.
- Ajax(Asynchronous JavaScript And XML):
비동기 실행과 Promise 객체
- 동기 실행과 비동기 실행자바 스크립트의 코드는 순차적으로 실행된다. (동기)비동기 실행에서 무시되는 코드는 중간에 다른 작업을 처리하다가 다시 돌아와서 마무리한다.
- 실행할 콜백이 여러개이면 동기적으로 실행됨.
- 비동기 함수는 이후에 있는 모든 코드를 실행한 뒤 콜백을 실행한다.
- setTimeout()함수를 통해 이를 테스트 해볼 수 있다.
- (예: 서버에 데이터를 요청하고 응답을 받는 경우)
- 만약 수행이 오래걸리는 코드가 있을 경우 이를 무시하고 다른 줄부터 수행하는 것을 비동기 실행이라 한다.
- 이전에 정리한 내용을 가져왔다.
- Promise 객체
- promise 작업에 관한 상태 정보를 갖고 있는 객체
- pending 작업이 진행 중인 상태
- fulfilled 작업이 성공적으로 완료된 상태
- rejected 작업이 실패한 상태
- promise 객체가 fulfilled 상태가 되면 promise 객체는 그 작업의 성공 결과도 함께 가진다
- fetch 함수의 경우 then 메소드의 첫 번째 argument(response)로 리턴하는 값이 그 작업의 성공 결과에 해당한다
- promise 객체가 rejected 상태가 되면 promise 객체는 그 작업의 실패 이유에 관한 정보도 함께 가진다.
- promise 작업에 관한 상태 정보를 갖고 있는 객체
- Promise Chaining이란?
- then() 메소드는 각 then() 메소드 뒤에 추가할 수 있다.
- then() 메소드는 새로운 프로미스 객체를 반환한다.
- 프로미스 체이닝은 then() 메소드를 연속적으로 추가하는 것을 의미한다.
- 각 후속 작업은 이전 작업이 성공할 때 시작하며, 이전 단계의 결과를 가지고 시작한다.
- then() 메소드는 다음 두 가지 경우에 실행된다:
- 콜백이 프로미스 객체를 반환할 때.
- 이 경우 then() 메소드가 반환하는 프로미스의 상태는 콜백이 반환하는 프로미스의 상태와 동일하게 된다.
- 콜백이 다른 값을 반환할 때.
- 이 경우 then() 메소드가 반환하는 프로미스의 상태는 충족된 상태가 되며, 작업 결과는 콜백이 반환하는 값과 동일하게 된다.
- 콜백이 프로미스 객체를 반환할 때.
- text(), json() 메소드도 프로미스 객체를 반환한다.
- 비동기 작업을 순차적으로 실행해야 할 때 프로미스 체이닝을 사용할 수 있다.
- rejected 상태가 되면 실행할 callback
- then() method의 second parameter로, 전달받은 promise state가 rejected일 때 실행할 callback을 넣어줄 수 있다
- 두 번째 callback의 parameter로는 작업 실패 정보가 넘어온다
- then 메소드 완벽하게 이해하기
- 실행된 callback이 어떤 값을 return하는 경우
- Promise object를 return하는 경우
- then 메소드가 return했던 promise object가 callback이 return한 promise object의 state와 result를 똑같이 따라 갖게 된다.
- Promise object 이외의 값을 return하는 경우
- then 메소드가 리턴했던 프로미스 객체는 fulfilled 상태가 되고 작업 성공 결과로 그 값을 갖게 된다.
- Promise object를 return하는 경우
- 실행된 콜백이 아무 값도 리턴하지 않는 경우
- 콜백이 undefined를 리턴한 것으로 간주된다.
- 실행한 콜백 내부에서 에러가 발생했을 때
- then 메소드가 리턴했던 프로미스 객체는 rejected 상태가 되고 작업 실패 정보로 해당 에러 객체를 갖게 된다.
- 아무런 콜백도 실행되지 않을 때
- then 메소드가 리턴했던 프로미스 객체는 이전 프로미스 객체와 동일한 상태와 결과를 갖게 된다.
- 실행된 callback이 어떤 값을 return하는 경우
- catch 메소드
- 프로미스 객체의 catch() 메소드로 then 메소드에 두 번째 콜백을 넣는 방법을 대신할 수 있다.
- 두 번째 콜백만 넣은 then 메소드와 똑같이 작동한다
- catch 메소드는 마지막에 써야 프로미스 체이닝에서 어느 프로미스 객체가 rejected 상태가 되더라도 모두 대응할 수 있다
- 에러가 발생했다고 해도 만약 실패한 작업 대신 다른 방법을 통해서 작업을 정상적으로 끝마칠 수 있는 상황이라면 catch 메소드를 중간에 사용할 수도 있다
- fetch('<https://jsonplaceholder.typicode.com/users>') .then((response) => response.text()) .catch((error) => { console.log(error); }) // .then(undefined, (error) => { console.log(error); }) .then((result) => { console.log(result); });
- finally 메소드
- 이전 프로미스 객체가 fulfilled 상태가 되든 rejected 상태가 되든 상관 없이 항상 내부콜백을 실행한다
- 보통 catch 메소드 뒤인 맨 밑 줄에 쓴다
- Promise 객체의 등장 배경
- 콜백 헬(callback hell)이라고 하는 문제로 인해 등장했다.
- 직접 만들어 보는 Promise 객체
프로미스 객체 생성 메소드를 통해 직접 생성해 볼 수 있다./* Promise {<pending>} // 2초 후 success */
- resolve로 작업 성공시 반환값, reject로 실패시 반환 값을 정의한다.
- const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('success'); }, 2000); }); p.then((result) => { console.log(result); });
- Promisify
- Promisify란 전통적인 형식의 비동기 실행 함수를 Promise 객체로 감싸서 그 Promise 객체를 리턴하는 형식으로 만드는 작업이다.
function wait(text, milliseconds) { setTimeout(() => text, milliseconds); } fetch('<https://jsonplaceholder.typicode.com/users>') ... .then((result) => { return wait(`${result}`, 2000); }) ...
- 위 상황에선 Promise 객체가 fullfilled되어도 바로 result를 사용할 수 없다.
function wait(text, milliseconds) { const p = new Promise((resolve, reject) => { setTimeout(() => { resolve(text); }, 2000); }); return p; }
- 이렇게 수정하여 직접 Promise객체를 생성해주면 된다.
- 이미 상태가 결정된 Promise 객체
const p = Promise.reject(new Error('fail')); // 작업 실패 정보로 문자열 'fail'을 갖는다
- const p = Promise.resolve('success'); // 작업 성공 결과로 문자열 'success'를 갖는다
- 여러 Promise 객체를 다루는 방법(심화)
Async/Await를 활용한 세련된 비동기 코드
- async/await이란?
- fetchAndPrint() 함수는 주석 처리된 프로미스 체이닝과 똑같이 작동한다
- async AsyncFunction 객체를 반환하는 하나의 비동기 함수를 정의하는 코드 중에서 프로미스 객체를 리턴하는 코드가 있음을 명시한다.
- await 비동기적으로 실행될 부분을 지정하는 키워드이다. 리턴 될 프로미스 객체 앞에 붙인다
- // fetch('URL') // .then((response) => response.text()) // .then((result) => { console.log(result); }); async function fetchAndPrint() { const response = await fetch('URL'); const result = await response.text(); console.log(result); } fetchAndPrint();
- catch문과 finally문
- 비동기적으로 실행되는 코드를 try문에 넣는다.
- 프로미스 객체가 rejected될 때 실행할 코드를 catch문에 넣는다.
- async function name() { try { const response = await fetch('<https://jsonplaceholder.typicode.com/users>'); const result = await response.text(); console.log(result); } catch (error) { console.log(error); } finally { console.log('exit'); } }
- async 함수가 리턴하는 Promise 객체
- 함수 내에서 프로미스 객체를 리턴하는 경우:
- 해당 프로미스 객체와 동일한 상태와 결과를 가진 프로미스 객체가 리턴된다.
- 작업 성공 시에는 작업 성공 결과를, 작업 실패 시에는 작업 실패 정보를 가진다.
- 프로미스 객체 이외의 값을 리턴하는 경우:
- fulfilled 상태의 프로미스 객체가 리턴된다.
- 리턴된 값은 작업 성공 결과로 간주된다.
- 아무 값도 리턴하지 않는 경우:
- fulfilled 상태의 프로미스 객체가 리턴된다.
- 작업 성공 결과는 undefined로 간주된다.
- async 함수 내부에서 에러가 발생했을 때:
- rejected 상태의 프로미스 객체가 리턴된다.
- 작업 실패 정보로 해당 에러 객체를 가진다.
- 함수 내에서 프로미스 객체를 리턴하는 경우:
- async function name() { try { const response = await fetch('<https://jsonplaceholder.typicode.com/users>'); const result = await response.text(); console.log(result); } catch (error) { console.log(error); } finally { console.log('exit'); } }
- async 함수 안의 async 함수
- async 함수도 프로미스 객체를 리턴하기 때문에, async 함수 앞에 await을 붙여서 또 다른 async 함수 안에 async 함수를 활용할 수 있다
- async를 붙이는 위치
- 함수 선언식(Function Declaration)
- 함수 표현식(Function Expression)
- Named Function Expression
- Anonymous Function Expression
- 화살표 함수(Arrow Function)
- 즉시 실행 함수(Immediately-invoked function expression, IIFE)
- async 함수를 작성할 때 주의해야할 성능 문제비동기 코드를 어떻게 쓰느냐에 따라 코드의 수행 시간을 단축시킬 수 있다.위 방식대로 코드를 작성하면,비동기 작업을 하나하나 기다린 뒤 다음 작업이 실행된다.이렇게 개선하면,각각의 비동기 작업을 기다리지 않고 다음 줄을 실행하게 된다.
- 이전에 배운 내용과 동일하여 정리 해둔 부분을 가져왔다.
유용한 실습
https://www.codeit.kr/topics/basics-of-js-web-dev/lessons/4383
'코드잇 부스트' 카테고리의 다른 글
React 웹 개발 시작하기 (0) 2024.07.13 쿠키, 세션, 스토리지, 로컬 스토리지 이해하기 (0) 2024.07.13 메타 태그 이해하기 (0) 2024.07.13 인터랙티브 자바스크립트 (0) 2024.07.13 자바스크립트로 리퀘스트 보내기 (0) 2024.06.28 - fetch 함수와 response 객체