티스토리 뷰

JSON이란?

JavaScript Object Notation의 약자로 JS에서 객체를 만들 때 사용하는 표현식을 의미

JSON is a text format for storing and transporting data(ref: W3C)

  • 다른 언어에서도 배열은 배열로, 객체는 객체로 전송할 수 있으며 일종의 데이터 표준
  • 인간과 기계 둘 다 이해하기 쉽고 데이터의 용량이 작다. -> XML의 대체제로 JSON을 사용, 설정의 저장이나 데이터 전송 등에 많이 사용됨
  • JSON은 JS의 모든 데이터 타입을 제공하는 것은 아니다.

JSON API

*ECMAScript5에는 JSON을 공식적으로 지원하는 API가 포함됨

  • JSON.parse(): 인자로 전달된 문자열(JSON의 text)을 자바스크립트 데이터로 변환한다.
  • JSON.stringify(): 인자로 전달된 자바스크립트의 데이터를 문자열로 변환한다.

주의: JSON에서 객체의 key에 해당하는 부분은 JS처럼 ""이 생략 가능하지 않다. ""(double quotation)을 써줘야 한다.

<body>
    <script>
      //JSON은 text format이기 때문에 text형식으로 값을 가져오는 것이 좋다. ->
      //특히,VSCode같은 소스 코드 편집기를 사용할 때에는 멋대로 객체의 key 큰따옴표("")를 생략하는 경우가 있는데
      //JSON에서는 key에 "" 더블 쿼테이션을 사용하라고 명시되어 있다.
      //아래와 같이 '{"key":value, "key":"value ..."}' 식으로 써주고
      //줄바꿈이 되어있는 부분에 \(역슬래쉬)로 구분을 해줘야 자바스크립트에서 인식을 한다. 
      //-> 역슬래쉬가 없으면 오류

      const info =
        '{\
        "id": "k9924",\
        "pass_word": 4423,\
        "recent_update": "12/31",\
        "active": false\
        }';
        console.log(info);
    
      //parse를 사용하면 JSON형식을 JS 데이터로 전환시켜준다.
      const infoObj = JSON.parse(info);
      console.log(infoObj);
      const infoJSON = JSON.stringify(infoObj);
      console.log(infoJSON);
    </script>
  </body>

이슈: ex1.html:1 Uncaught SyntaxError: Unexpected token } in JSON at position 114

  • 이유: 습관적으로 프로퍼티끼리의 구분을 위해서 콤마를 쓰던 것 때문에 구문오류
  • 해결방안: 맨 아랫줄에 있던 false 뒤에 있던 ","을 삭제하니 정상가동


JSON 없이 Ajax 사용하기(서버와 통신하기)

JSON의 진가는 서버와 통신할 때 드러난다.

 

 

지난 Ajax 수업의 내용을 개조해서 타임라인의 항목을 리스트로 표현하는 에플리케이션을 만들어보자

time.php (서버측 예시)

<?php
    $timezones = ["Asia/Seoul", "America/New_York"];
    echo implode(',', $timezones); 
    ?>
  • 서버 쪽(.php)에서는 타임라인의 리스트를 콤마로 구분해서 전달한다.
  • 코드 결과: Asia/Seoul,America/New_York  <-클라이언트 측에서 이 데이터를 받아서 처리한다.

ex1.html (클라쪽 예시)

 <body>
    <p id="timezones"></p>
    <input type="button" id="execute" value="execute" />
    <script>
      document
        .querySelector("input")
        .addEventListener("click", function (event) {
          const xhr = new XMLHttpRequest();
          xhr.open("GET", "./time.php");
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
              const _tzs = xhr.responseText;
              //_tzs에 Asia/Seoul,America/New_York 가 담겨있음 _tzs는 문자열 객체
              //   문자열 객체의 .split() 메소드를 사용해서 인자로 전달된
              // ","콤마(*구분자(seperator): optional, string이어야 함)를 찾아서 그것을 기준으로
              //   각각을 원소로 쪼갠 뒤 그 원소를 담은 배열을 반환한다.
              const tzs = _tzs.split(",");
              const _str = "";
              for (var i = 0; i < tzs.length; i++) {
                //tzs 배열에 담긴 원소들을 순회하면서 생긴 결과물을 임시변수인_str에 하나씩 추가해준다.
                _str += "<li>" + tzs[i] + "</li>";
              }
              _str = "<ul>" + _str + "</ul>";
              //마지막 결과물을 id가 timezone인 p태그의 content로 ul>li태그s 를 삽입해줍니다.
              document.querySelector("#timezones").innerHTML = _str;
            }
          };
          xhr.send();
        });
    </script>
  </body>

정리: JSON을 사용하지 않으면 위와 같이 서버쪽(PHP) 배열을 문자화시켜서 클라로 보냈다가 다시 클라쪽에서 쪼개진 데이터를 배열화하는 복잡스러운 일이 생긴다. 서로에게 전송하는 데이터가 1차원 배열(적은 양의 데이터)이라면 콤마로 구분하여 데이터를 전송하는 방법이 나쁜 방법은 아니지만 만약에 전송하려는 데이터가 2차원, 다차원 배열 혹은 복잡한 객체일 경우, 작업하기가 기하급수적으로 어려워진다.

  • php(서버측)에서는 배열을 JS으로 전달할 수 없기 때문에(서로 다른 언어이므로) 문자로 변경하여 전송해준다.
    • echo implode(',', $timezones);
  • JavaScript(클라이언트측)에서는 서버로부터 전달받은 문자를 프로그래밍적으로 제어하기 위해 다시
    • const tzs = _tzs.split(','); 를 통해 배열로 만들고 있다. 이 과정에서 ,(콤마)를 통해 데이터를 쪼개서 배열로 다시 만들고 있음

+

String.prototype.split()

문자열 객체의 메소드로 인자의 값(separator)을 기준으로 문자를 잘라서 배열로 만든다.

▶문법: split(separator, limit)

  • separator (Optional) : 원본 문자열을 끊어야 할 부분을 나타내는 문자열을 나타낸다. 실제 문자열이나 정규표현식을 받을 수 있다. 
  • limit (Optional) : 끊어진 문자열의 최대 개수를 나타내는 정수이다. 배열의 원소가 limit 개가 되면 멈춘다.

▶반환값: 주어진 문자열을 separator 마다 끊은 부분 문자열을 담은 Array 객체


 

JSON의 적용(with. Ajax)

ex1.html내부의 예제는 JSON을 사용하지 않았을 때 어떻게 클라와 서버가 통신하는지에 대해 다루고 있다. 그렇다면 이전 예시를 JSON화 시키려면 어떻게 하면 될까?
  • 우선 서버쪽 time.php 코드에서 echo implode(',', $timezones); -> echo json_encode($timezone); 으로 변경해준다. *json_encode는 PHP의 데이터를 JSON 형식으로 전환해주는 PHP 내장함수이다.
  • 결과: ["Asia\/Seoul,America\/New_York"] //이렇게하면 JS에 JSON화된 서버측 데이터를 넘겨줄 수 있다.

서버로부터 데이터를 전달받는 방법 (서버 -(데이터)-> 클라이언트)

<body>
    <p id="timezones"></p>
    <input type="button" id="execute" value="execute" />
    <script>
      document
        .querySelector("input")
        .addEventListener("click", function (event) {
          const xhr = new XMLHttpRequest();
          xhr.open("GET", "./time.php");
          xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
              const _tzs = xhr.responseText;
              //   const tzs = _tzs.split(",");
              // 위의 코드는 JSON을 사용하지 않을 때 배열을 만들기 위한 코드였다.
              // 아래의 코드를 통해서 서버에서 전송한 JSON 데이터를 JS의 배열로 만들 수 있다.
              const tzs = JSON.parse(_tzs);
              const _str = "";
              for (var i = 0; i < tzs.length; i++) {
                _str += "<li>" + tzs[i] + "</li>";
              }
              _str = "<ul>" + _str + "</ul>";
              document.querySelector("#timezones").innerHTML = _str;
            }
          };
          xhr.send();
        });
    </script>
  </body>​

아래의 내용은 위의 예시 코드에서 변경된 내용이다. 

 

기존 코드 

const tzs = _tzs.split(",");

 

업데이트된 코드

 const tzs = JSON.parse(_tzs);

 


서버로 데이터 전송

서버로 JSON 데이터를 전송하는 것도 가능하다. (클라 -(데이터)-> 서버)

 

클라쪽 코드

  • open() 메소드의 첫번째 인자로 'POST'를 주고 두번째 인자로 '서버측 url' 을 준다. 
  • xhr.setRequestHeader("Content-Type", "application/json") //xhr 은 XMLHttpRequest 객체를 담은 변수
  • xhr.send(JSON.stringify(data)); //*data 전달하려는 JS데이터

서버쪽 코드 

<?php
$data = json_decode(file_get_contents('php://input'), true);
$d1 = new DateTime;
$d1->setTimezone(new DateTimezone($data['timezone']));
echo $d1->format($data['format']);
?>

PHP는 잘 모름..

 

댓글