jQuery Ajax & JSON

jhree333·2023년 11월 12일

jQuery

목록 보기
2/4

Introduction

  • 브라우저에서 웹페이지를 요청하거나 링크를 클릭하면 화면 전환이 발생. 이것은 브라우저와 서버와의 통신에 의한 것.
  • 서버는 요청받은 페이지(HTML)를 반환하는데 이때 HTML에서 로드하는 CSS나 JavaScript 파일들도 같이 반환. 클라이언트의 요청에 따라 서버는 정적인 파일을 반환할 수도 있고 서버 사이드 프로그램이 만들어낸 파일이나 데이터를 반환할 수도 있음. 서버로부터 웹페이지가 반환되면 클라이언트(브라우저)는 이를 렌더링하여 화면에 표시.
  • Ajax(Asynchronous JavaScript and XML)는 자바스크립트를 이용해서 비동기적(Asynchronous)으로 서버와 브라우저가 데이터를 교환할 수 있는 통신 방식을 의미. 서버로부터 웹페이지가 반환되면 화면 전체를 갱신해야 하는데 페이지 일부만을 갱신하고도 동일한 효과를 볼 수 있도록 하는 것이 Ajax. 페이지 전체를 로드하여 렌더링할 필요가 없고 갱신이 필요한 일부만 로드하여 갱신하면 되므로 빠른 퍼포먼스와 부드러운 화면 표시 효과를 기대할 수 있음.
  • 서버는 HTML, XML, JSON등을 반환하는데 Ajax을 위한 데이터 형식은 JSON(JavaScript Object Notation)을 사용하는 것이 일반적.

동기식 처리 모델 vs 비동기식 처리 모델

  • 동기식 처리 모델(Synchronous processing model)은 직렬적으로 작업을 수행. 즉, 작업은 순차적으로 실행되며 어떤 작업이 수행 중이면 다음 작업은 대기하게 됨. 예를 들어 서버에서 데이터를 가져와 화면에 표시하는 작업을 수행할 경우 서버에 데이터를 요청하고 데이터가 전달될 때까지 이후 작업들은 중단(Blocking).
  • 비동기식 처리 모델(Asynchronous processing model or Non-Blocking processing model)은 병렬적으로 작업을 수행. 즉, 작업이 종료되지 않은 상태라도 대기하지 않고 다음 작업을 실행. 예를 들어 서버에서 데이터를 가져와 화면에 표시하는 작업을 수행할 경우 서버에 데이터를 요청한 이후 서버로부터 데이터가 전달될 때까지 대기하지 않고(Non-Blocking) 즉시 다음 작업을 수행. 이후 서버로부터 데이터가 전달되면 이벤트가 발생되고 이벤트 핸들러가 데이터를 가지고 수행할 작업을 계속하여 수행. 자바스크립트의 대부분의 DOM 이벤트와 Timer 함수(setTimeout, setInterval), Ajax 요청은 비동기적으로 동작.

Ajax 요청 및 응답 처리

// XMLHttpRequest 객체의 생성
let req = new XMLHttpRequest();
// 비동기 방식으로 Request를 오픈한다
req.open('GET', 'data/test.json', true);
// Request를 전송한다
req.send();

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

  // readyStates는 XMLHttpRequest의 상태(state)를 반환
  // readyState: 4 => DONE(서버 응답 완료)
  if (req.readyState === XMLHttpRequest.DONE) {
    // status는 response 상태 코드를 반환 : 200 => 정상 응답
    if(req.status == 200) {
      console.log(req.responseText);
    } else {
      console.log("Error!");
    }
  }
};

JSON

let o = {
  name: "Lee",
  gender: "male"
};

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

let arr = [1, 5, "false"];

// 배열 객체 => 문자열
let strArray = JSON.stringify(arr);
console.log(typeof strArray, strArray); // string '[1, 5, "false"]'

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

// 문자열 => 배열 객체
let objArray = JSON.parse(strArray);
console.log(typeof objArray, objArray); // object [1, 5, "false"]

Web Server

  • 웹서버(Web Server)는 브라우저와 같은 클라이언트로부터 HTTP 요청을 받아들이고 HTML 문서와 같은 웹 페이지를 반환하는 컴퓨터 프로그램.
  • Ajax는 웹서버와의 통신이 필요하므로 예제를 실행하기 위해서는 웹서버가 필요. 아래의 방법 중에서 한가지를 선택하여 웹서버를 설치.
  1. Simple Webserver with Express
  2. MAMP
  3. Mongoose Web Server

Ajax

Load HTML

  • Ajax를 이용하여 웹페이지에 추가하기 가장 손쉬운 데이터 형식은 HTML. 별도의 작업없이 전송받은 데이터를 DOM에 추가하면 됨.
      // XMLHttpRequest 객체의 생성
      let req = new XMLHttpRequest();
      // 비동기 방식으로 Request를 오픈한다
      req.open('GET', 'data/data.html', true);
      // Request를 전송한다
      req.send();

      // Event Handler
      req.onreadystatechange = function () {
        // 서버 응답 완료 && 정상 응답
        if (req.readyState === XMLHttpRequest.DONE) {
          if (req.status == 200) {
            console.log(req.responseText);

            document.getElementById('content').innerHTML = req.responseText;

            // document.getElementById('content').insertAdjacentHTML('beforeend', req.responseText);
          } else {
            console.log('[' + req.status + ']: ' + req.statusText);
          }
        }
      };

Load JSON

  • 서버로부터 브라우저로 전송된 JSON 데이터는 문자열. 이 문자열을 객체화하여야 하는데 이를 역직렬화(Deserializing). 역직렬화를 위해서 내장 객체 JSON의 static 메소드인 JSON.parse()를 사용.
// XMLHttpRequest 객체의 생성
      let req = new XMLHttpRequest();

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

      req.onreadystatechange = function () {
        // 서버 응답 완료 && 정상 응답
        if (req.readyState === XMLHttpRequest.DONE) {
          if (req.status == 200) {
            console.log(req.responseText);

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

            // JSON → HTML String
            let newContent = '';
            newContent += '<div id="tours">';
            newContent += '<h1>Guided Tours</h1>';
            newContent += '<ul>';
            for (let i = 0; i < responseObject.tours.length; i++) {
              newContent += '<li class="' + responseObject.tours[i].region + ' tour">';
              newContent += '<h2>' + responseObject.tours[i].location + '</h2>';
              newContent += '<span class="details">' + responseObject.tours[i].details + '</span>';
              newContent += '<button class="book">Book Now</button>';
              newContent += '</li>';
            }
            newContent += '</ul></div>';

            document.getElementById('content').innerHTML = newContent;

            // document.getElementById('content').insertAdjacentHTML('beforeend', newContent);

          } else {
            console.log('[' + req.status + ']: ' + req.statusText);
          }
        }
      };

Load JSONP

  • 요청에 의해 웹페이지가 전달된 서버와 동일한 도메인의 서버로 부터 전달된 데이터는 문제없이 처리할 수 있음. 하지만 보안상의 이유로 다른 도메인(http와 https, 포트가 다르면 다른 도메인으로 간주한다)으로의 요청(크로스 도메인 요청)은 제한. 이것을 동일출처원칙(Same-origin policy).
  • 동일출처원칙을 우회하는 방법은 세가지가 있음.
  1. 웹서버의 프록시 파일 서버에 원격 서버로부터 데이터를 수집하는 별도의 기능을 추가하는 것. 이를 프록시(Proxy).
  2. JSONP script 태그의 원본 주소에 대한 제약이 존재하지 않는데 이것을 이용하여 다른 도메인의 서버에서 데이터를 수집하는 방법. 자신의 서버에 함수를 정의하고 다른 도메인의 서버에 얻고자 하는 데이터를 인수로 하는 함수 호출문을 로드하는 것.
function showTours(data) {
      console.log(data); // data: object

      // JSON → HTML String
      var newContent = '';
      newContent += '<div id="tours">';
      newContent += '<h1>Guided Tours</h1>';
      newContent += '<ul>';
      for (var i = 0; i < data.tours.length; i++) {
        newContent += '<li class="' + data.tours[i].region + ' tour">';
        newContent += '<h2>' + data.tours[i].location + '</h2>';
        newContent += '<span class="details">' + data.tours[i].details + '</span>';
        newContent += '<button class="book">Book Now</button>';
        newContent += '</li>';
      }
      newContent += '</ul></div>';

      document.getElementById('content').innerHTML = newContent;
    }
  1. Cross-Origin Resource Sharing HTTP 헤더에 추가적으로 정보를 추가하여 브라우저와 서버가 서로 통신해야 한다는 사실 방법. W3C 명세에 포함되어 있지만 최신 브라우저에서만 동작하며 서버에 HTTP 헤더를 설정.

Ajax with jQuery

Low-Level Interface

Load HTML

    $.ajax({
      url: "data/data.html",
      cache: false
    })
      .done(function(data, textStatus, jqXHR) {
        $("#content").html(data);
      })
      .fail(function(jqXHR, textStatus, errorThrown){
        console.log("fail: ", jqXHR);
      })
      .always(function(data, textStatus, jqXHR){
        console.log("always: ", data);
      });

Load JSON

 $.ajax({
      url: "data/data.json",
      dataType: "json"
    })
      .done(function(data) {
        let newContent = '';
        newContent += '<div id="tours">';
        newContent += '<h1>Guided Tours</h1>';
        newContent += '<ul>';
        for (var i = 0; i < data.tours.length; i++) {
          newContent += '<li class="' + data.tours[i].region + ' tour">';
          newContent += '<h2>' + data.tours[i].location + '</h2>';
          newContent += '<span class="details">' + data.tours[i].details + '</span>';
          newContent += '<button class="book">Book Now</button>';
          newContent += '</li>';
        }
        newContent += '</ul></div>';

        $("#content").html(newContent);
      })
      .fail(function(jqXHR, textStatus, errorThrown){
        console.log("fail: ", jqXHR);
      })
      .always(function(data, textStatus, jqXHR){
        console.log("always: ", data);
      });

Load JSONP

 $.ajax({
      url: "http://poiemaweb.com/assets/data/data-jsonp.js",
      dataType: "jsonp",
      jsonpCallback: "showTours"
    })
      .done(function(data, textStatus, jqXHR){
        console.log("done: ", data);

        let newContent = '';
        newContent += '<div id="tours">';
        newContent += '<h1>Guided Tours</h1>';
        newContent += '<ul>';
        for (let i = 0; i < data.tours.length; i++) {
          newContent += '<li class="' + data.tours[i].region + ' tour">';
          newContent += '<h2>' + data.tours[i].location + '</h2>';
          newContent += '<span class="details">' + data.tours[i].details + '</span>';
          newContent += '<button class="book">Book Now</button>';
          newContent += '</li>';
        }
        newContent += '</ul></div>';

        $("#content").html(newContent);
      })
      .fail(function(jqXHR, textStatus, errorThrown){
        console.log("fail: ", jqXHR);
      })
      .always(function(data, textStatus, jqXHR){
        console.log("always: ", data);
      });

Shorthand Method

jQuery.get()

      $.get("data/data.html", function(data){
        $("#content").html(data);
      });

jQuery.getJSON()

 $.getJSON("data/data.json", function(data){

        let newContent = '';
        newContent += '<div id="tours">';
        newContent += '<h1>Guided Tours</h1>';
        newContent += '<ul>';
        for (let i = 0; i < data.tours.length; i++) {

          newContent += '<li class="' + data.tours[i].region + ' tour">';
          newContent += '<h2>' + data.tours[i].location + '</h2>';
          newContent += '<span class="details">' + data.tours[i].details + '</span>';
          newContent += '<button class="book">Book Now</button>';
          newContent += '</li>';
        }
        newContent += '</ul></div>';

        $("#content").html(newContent);
      });

jQuery.getScript()

  • HTTP GET request를 사용하여 서버로부터 JavaScript 파일을 로드한 후 실행.

jQuery.post()

  • HTTP GET request를 사용하여 서버로부터 데이터를 로드.

load()

  • 서버로부터 HTML 데이터를 로드하고 매치드셋에 적용
      $("#content").load("data/data.html", function(){
        console.log("Load was performed.");
      })
profile
안녕하세요.

0개의 댓글