Ajax (Asynchronous Javascript and XML)

  • 브라우저에서 웹페이지를 요청하거나 링크를 클릭하면 브라우저와 서버와의 통신에 의해 화면 갱신이 발생한다.

전통적인 방식

  • 서버는 요청 받은 페이지를 반환하는데 이 때 CSS,JS 파일들도 같이 반환된다.
  • 서버로부터 웹페이직가 반환되면 이를 브라우저에 렌더링하여 화면에 표시한다.

Ajax 방식

  • Ajax는 JS를 이용하여 비동기적으로 서버와 브라우저가 데이터를 교환할 수 있는 통신방식을 의미한다.
  • 서버로부터 웹페이지 반환 시 화면 전체를 갱신하는 것이 아닌, 페이지 일부만 갱신한다.
  • 빠른 퍼포먼스와 부드러운 화면 표시 효과를 볼 수 있다.

JSON ( Javascript Object Notation)

  • 클라이언트와 서버간에는 데이터 교환이 필요하다.
  • JSON은 클라이언트와 서버 간 데이터 교환을 위해 규칙 즉, 데이터 포맷을 말한다.
  • 객체 리터럴과 흡사하지만 JSON은 순수한 텍스트로 구성된 규칙이 있는 데이터 구조이다.
  • 키는 반드시 큰 따옴표로 둘러싸야 한다.
  • 작은따옴표 불가‼️
{
  "name": "Lee",
  "gender": "male",
  "age": 20,
    
  // ✖️작은 따옴표✖️
  'alive': true 
  
}

JSON.stringify()

  • 객체를 JSON 형식의 문자열로 변환
const o = { name: 'Lee', gender: 'male', age: 20 };

// 객체 => JSON 형식의 문자열
const strObject = JSON.stringify(o);
console.log(typeof strObject, strObject);
// string {"name":"Lee","gender":"male","age":20}

// 객체 => JSON 형식의 문자열 + prettify
const strPrettyObject = JSON.stringify(o, null, 2);
console.log(typeof strPrettyObject, strPrettyObject);
/*
string {
  "name": "Lee",
  "gender": "male",
  "age": 20
}
*/

JSON.parse()

  • JSON 데이터를 가진 문자열을 객체로 변환한다.
  • 역직렬화 : 서버로부터 브라우저로 전송된 JSON 데이터는 문자열객체화 하는 것
  • 역직렬화를 위해 내장객체 JSON의 static 메소드인 JSON.parse()를 사용하는 것이다.
const o = { name: 'Lee', gender: 'male', age: 20 };

// 객체 => JSON 형식의 문자열
const strObject = JSON.stringify(o);
console.log(typeof strObject, strObject);
// string {"name":"Lee","gender":"male","age":20}

// JSON 형식의 문자열 => 객체
const obj = JSON.parse(strObject);
console.log(typeof obj, obj); 
// object { name: 'Lee', gender: 'male' }

XMLHttpRequest

  • 브라우저는 XMLHttpRequest 객체를 이용하여 Ajax요청을 생성학고 전송한다.
  • 서벅가 브라우저의 요청에 대해 응답을 반환하면 같은 XMLHttpRequest객체가 그 결과를 처리한다.

💡 Ajax request

  • Ajax 요청하기
// XMLHttpRequest 객체의 생성
const xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET', 'url');
// Request를 전송한다
xhr.send();
  • xhr.open( method, url [ ,async ] )
    • method : HTTP method ("GET","POST","PUT","DELETE")
    • url : 요청을 보낼 URL
    • async : 비동기 조작 여부, 옵션으로 default는 true이며 비동기방식으로 동작함
  • xhr.send( )
    • 준비된 요청을 서버에 전달한다.
    • GET : URL의 일부분인 쿼리문자열로 데이터를 서버로 전송
    • POST : 데이터(페이로드)를 Request Body에 담아 전송
    • 만약 요청 메서드가 GET이라면 send()의 인수는 무시되고 request body는 null로 설정된다.

💡 xhr.setResquestHeader

  • HTTP RequsetHeader의 값을 설정
  • 반드시 xhr.open() 호출 이후에 호출한다.
    • Content-type : requset body에 담아 전송할 데이터의 MIME-type의 정보를 표현
    • Accept : HTTP 클라이언트가 서버에 요청할 때 서버가 센드백할 데이터의 MIME-type을 Accept로 지정 할 수 있다.
      만약 Accept 헤더를 설정하지 않으면 send()가 호출될 때 */*으로 전송
// json으로 전송하는 경우
xhr.open('POST', '/users');

// 클라이언트가 서버로 전송할 데이터의 MIME-type 지정: json
xhr.setRequestHeader('Content-type', 'application/json');

const data = { id: 3, title: 'JavaScript', author: 'Park', price: 5000};

xhr.send(JSON.stringify(data));

// 서버가 센드백할 데이터의 MIME-type 지정: json
xhr.setRequestHeader('Accept', 'application/json');

💡 Ajax response

  • xhr.send()를 통해 서버 Request를 전송하면
    서버는 Response를 반환하는데 언제 클라이언트에 도달했는지 알 수 없다
  • xhr.onreadystateChange는 Response까 클라이언트에 도달하여 발생된 이벤트를 감지하고 콜백함수를 실행
  • 이때 이벤트는 Request에 어떠한 변화가 발생한 경우
  • xhr.readyState프로퍼티가 변경된 경우 발생
  • xhr.readyState : XMLHttpRequset 객체는 response가 클라이언트에 도달했는지를 추적할 수 있는 프로퍼티를 제공
    • 0 / UNSENT : xhr.open() 호출 이전
    • 1 / OPENED : xhr.open() 호출 완료
    • 2 / HEADERS_RECEIVED : xhr.send() 호출 완료
    • 3 / LOADING : 서버 응답 중 (xhr.responseText 미완성 상태)
    • 4 / DONE : 서버 응답 완료
// XMLHttpRequest 객체의 생성
var xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET', 'data/test.json');
// Request를 전송한다
xhr.send();

// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 콜백함수(이벤트 핸들러)를 호출한다.
xhr.onreadystatechange = function (e) {
  // 이 함수는 Response가 클라이언트에 도달하면 호출된다.

  // readyStates는 XMLHttpRequest의 상태(state)를 반환
  // readyState: 4 => DONE(서버 응답 완료)
  if (xhr.readyState !== XMLHttpRequest.DONE) return;

  // status는 response 상태 코드를 반환 : 200 => 정상 응답
  if(xhr.status === 200) {
    console.log(xhr.responseText);
  } else {
    console.log('Error!');
  }
};
  • xhr.readyState가 4인 경우, 서버 응답 완료 상태이므로 이후
  • xhr.status가 200(정상응답)을 확인하고
  • 정상인 경우, xhr.responseText를 취득
  • xhr.responseText는 서버가 전송한 데이터가 담겨있다.
  • 만약 서버 응답 완료 상태만 반응하려면 readystateChange 대신 load 이벤트를 사용해도 된다.
  • load 이벤트는 서버응답 완료인 경우에만 발생
// XMLHttpRequest 객체의 생성
var xhr = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
xhr.open('GET', 'data/test.json');
// Request를 전송한다
xhr.send();

// load 이벤트는 서버 응답이 완료된 경우에 발생한다.
xhr.onload = function (e) {
  // status는 response 상태 코드를 반환 : 200 => 정상 응답
  if(xhr.status === 200) {
    console.log(xhr.responseText);
  } else {
    console.log('Error!');
  }
};

Ajax JSON 예제

  • 서버로부터 받아온 JSON 문자열 데이터를
  • 역직렬화 = 문자열의 객체화 해주는데
  • 내장객체 static메소드 JSON.parse()를 사용
{
  "tours": [
    {
      "region": "usa",
      "location": "New York, USA",
      "details": "$1,899 for 7 nights"
    },
    {
      "region": "europe",
      "location": "Paris, France",
      "details": "$2,299 for 7 nights"
    },
    {
      "region": "asia",
      "location": "Tokyo, Japan",
      "details": "$3,799 for 7 nights"
    }
  ]
}
<!-- 루트 폴더(webserver-express/public)/loadjson.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://poiemaweb.com/assets/css/ajax.css">
  </head>
  <body>
    <div id="content"></div>

    <script>
      // XMLHttpRequest 객체의 생성
      var xhr = new XMLHttpRequest();

      // 비동기 방식으로 Request를 오픈한다
      xhr.open('GET', 'data/data.json');
      // Request를 전송한다
      xhr.send();

      xhr.onreadystatechange = function () {
        // 서버 응답 완료 && 정상 응답
        if (xhr.readyState !== XMLHttpRequest.DONE) return;

        if (xhr.status === 200) {
          console.log(xhr.responseText);

          // Deserializing (String → Object)
          responseObject = JSON.parse(xhr.responseText);

          // JSON → HTML String
          let newContent = '<div id="tours"><h1>Guided Tours</h1><ul>';

          responseObject.tours.forEach(tour => {
            newContent += `<li class="${tour.region} tour">
                <h2>${tour.location}</h2>
                <span class="details">${tour.details}</span>
                <button class="book">Book Now</button>
              </li>`;
          });

          newContent += '</ul></div>';

          document.getElementById('content').innerHTML = newContent;
        } else {
          console.log(`[${xhr.status}] : ${xhr.statusText}`);
        }
      };
    </script>
  </body>
</html>

REF

profile
냠소현 개발일지

0개의 댓글