Front-end Developer

0%

Ajax

Ajax(Asynchronous Javascript And XML)

자바스크립트를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식. 서버와 통신하기 위해 XMLHttpRequest 객체를 사용하는 것.

이전 웹페이지는 완전한 HTML을 서버로부터 전송받아 웹페이지 전체를 처음부터 렌더링하는 방식으로 동작했다. 따라서 화면이 전환되면 또 웹페이지 전체를 처음부터 다시 렌더링하게 된다. 이렇게 되면 굳이 변경할 필요가 없는 부분도 서버로부터 전달받는 불필요한 데이터 통신이 발생하고, 화면의 순간적으로 깜빡거리는 현상이 발생한다. 또한 서버로부터 응답을 받기 전까지 블로킹되는 문제가 발생한다. Ajax가 등장하면서 굳이 데이터를 변경하지 않아도 되는 부분은 그대로 두고, 서버에서 필요한 데이터만 전송받아 변경이 필요한 부분만 렌더링할 수 있고, 화면의 전환도 부드러워졌다.

JSON(JavaScript Object Notation)

javascript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반 표준 포맷으로 웹 어플리케이션에서 데이터를 전송할 때 일반적으로 사용한다.

클라이언트와 서버 간의 HTTP 통신을 위한 텍스트 데이터 포맷
객체 리터럴처럼 키와 값으로 구성된 순수한 텍스트

  • 키는 반드시 큰따옴표로 묶어야 한다.
  • 값도 문자열인 경우 반드시 큰따옴표로 묶어야 한다.
  • 순수한 데이터 포맷이므로 프로퍼티만 담을 수 있고, 메서드는 담을 수 없다.

JSON parse() / stringify()

request.responseType = ‘json’;

위와 같이 응답 타입이 json이면 편리하지만 json 문자열을 그대로 받아서 객체로 변환시키거나, 네트워크에 전송할 때 객체를 JSON 타입으로 변환시켜야 하는 경우가 흔하다. 이는 아래와 같은 방법으로 변환한다.

JSON.parse

서버 -> JSON 데이터(문자열) -> 클라이언트 -> JSON.parse(역직렬화) -> 객체(화)

JSON 문자열을 매개변수로서 수용하고, 일치하는 자바스크립트 객체로서 변환.

JSON.stringify

클라이언트 -> 객체 -> JSON.stringify(직렬화) -> 문자열 -> 서버

stringify(): 객체를 매개변수로서 수용하고, JSON 문자열 형태로 변환.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const obj = { name: "lee", job: "web developer" };
console.log(typeof obj); // object

// 객체를 문자로 변환
const objToJson = JSON.stringify(obj);
console.log(typeof objToJson, objToJson);
// string {"name":"lee","job":"web developer"}

const json = objToJson;
console.log(typeof objToJson, objToJson);
// string {"name":"lee","job":"web developer"}

//문자를 객체로 변환
const jsonToObj = JSON.parse(objToJson);
console.log(typeof jsonToObj, jsonToObj);
// object {name: "lee", job: "web developer"}

XMLHttpRequest

XMLHttpRequest -> XMLHttpRequestEventTarget -> EventTarget

브라우저는 주소창이나 HTML의 form 태그 또는 a 태그를 통해 HTTP 요청 전송 기능을 기본 제공한다. 자바스크립트를 사용하여 HTTP 요청을 전송하려면 XMLHttpRequest 객체를 사용한다. XHR 객체는 서버와 상호작용하기 위해 사용되므로, 전체 페이지의 새로고침 없이도 URL로부터 데이터를 받아 올 수 있다.

  1. XMLHttpRequest 객체 생성

const xhr = new XMLHttpRequest();

생성자는 XMLHttpRequest 를 초기화하며, 다른 모든 메소드 호출 이전에 호출되어야 한다.

  1. HTTP 요청 전송

XMLHttpRequest.prototype.open

  • xhr.open(요청메서드, 요청을 전송할 url, 비동기요청여부 - 기본값 true)
  • XMLHttpRequest.prototype.open 메서드로 HTTP 요청을 초기화한다.
  • 필요에 따라 XMLHttpRequest.prototype.setRequestHeader 메서드로 특정 HTTP 요청의 헤더 값을 설정한다.

XMLHttpRequest.prototype.send

XMLHttpRequest.prototype.send 메서드로 HTTP 요청을 전송한다.

  • GET: 데이터를 URL의 일부분인 쿼리 문자열(query string)로 서버에 전송
  • POST: 데이터(페이로드)를 요청 몸체(request body)에 담아 전송
  • GET, DELETE는 페이로드 X
  • POST, PUT, PATCH는 페이로드 O
  • 페이로드가 개체일 경우 반드시 JSON.stringify를 사용한 후 전달한다.

XMLHttpRequest.prototype.setRequestHeader

특정 HTTP 요청의 헤더 값을 설정한다. setRequestHeader 메서드는 반드시 open 메서드를 호출한 이후에 호출

  1. HTTP 응답 처리
    XMLHttpRequest 객체가 발생시키는 이벤트를 캐치하여 처리하는데, send 메서드를 통해 서버에 전달된 HTTP 요청이 서버로부터 클라이언트에 언제 도달할 지 알 수 없으므로 이벤트를 캐치하여 현재 상태를 확인해야 한다.
    • readystatechange 이벤트: HTTP 요청의 현재 상태를 나타내는 readyState 프로퍼티 값이 변경된 경우 발생
    • onload 이벤트: HTTP 요청이 성공적으로 완료된 경우 발생한다. 따라서 load 이벤트를 캐치하는 경우 xhr.readyState가 XMLHttpRequest.DONE인지 확인할 필요가 없다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// {...}
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);
}
};

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

References
MDN
MDN
MDN
poiemaweb