JavaScript(4) JSON

김재홍·2022년 3월 3일
0
post-thumbnail

JSON이란 무엇인가

JSON은 자바스크립트 객체 문법을 따르는 문자기반의 데이터 포맷이다.
웹 어플리케이션에서 데이터를 전송할 때 주로 사용한다.

JSON은 문자열 형태로 존재하는데 이는 네트워크를 통해 전송할 때 아주 유용하다.
데이터에 접근하기 위해서는 네이티브 JSON 객체로 변환될 필요가 있는데
자바스크립트는 JSON 전역 객체를 통해 문자열과 JSON 객체의 상호변환을 지원한다.

개별 JSON 객체를 .json 확장자를 가진 단순 텍스트 파일에 저장할 수 있다.

JSON 구조

위에서 설명했듯이 JSON은 자바스크립트 객체 리터럴 문법을 따르는 문자열이다.
JSON 안에는 마찬가지로 자바스크립트의 기본 데이터 타입인 문자열, 숫자, 배열, 불리언
그리고 다른 객체를 포함할 수 있다.

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

이 객체를 자바스크립트 프로그램에서 로드하고, 예를들어 superHeroes 라는 이름의 변수에 파싱하면
점/브라켓 표현법을 통해 객체 내 데이터에 접근할 수 있게 된다.

superHeroes.homeTown
superHeroes['actice']

하위 계층의 데이터에 접근하려면, 간단하게 프로퍼티 이름과 배열 인덱스의 체인을 통해 접근하면 된다.
예를 들어 superHeroes의 두 번째 member의 세 번째 power에 접근하려면 아래처럼 하면 된다.

> superHeroes['member'][1]['powers'][2]

JSON에서의 배열

JSON 텍스트는 기본적으로 자바스크립트의 오브젝트와 비슷하다고 했는데
그것은 대부분 맞다. "대부분 맞다고"라고 말한 이유는 자바스크립트의 배열 또한
JSON에서 유효하기 때문이다.

[
  {
    "name": "Molecule Man",
    "age": 29,
    "secretIdentity": "Dan Jukes",
    "powers": [
      "Radiation resistance",
      "Turning tiny",
      "Radiation blast"
    ]
  },
  {
    "name": "Madame Uppercut",
    "age": 39,
    "secretIdentity": "Jane Wilson",
    "powers": [
      "Million tonne punch",
      "Damage resistance",
      "Superhuman reflexes"
    ]
  }
]

위 예제는 완벽한 형태의 JSON이다. 배열의 요소에 접근하기 위해서는 배열의 인덱스를 사용하면 된다.

주의할 점

  • JSON은 순수히 데이터 포맷이다. 오직 속성만 담을 수 있다. 함수는 담을 수 없다.
  • JSON은 문자열과 속성의 이름 작성시 큰 따옴표만을 사용해야 한다. 작은 따옴표 사용불가
  • 콤마나 콜론을 잘못 배치하는 사소한 실수로 JSON파일이 잘못되어 작동하지 않을 수 있다.
    JSONLint 같은 어플리케이션을 사용해 JSON 유효성 검사를 할 수 있다.
  • JSON은 JSON내부에 포함할 수 있는 모든 형태의 데이터 타입을 취할 수 있다.
    즉, 배열이나 오브젝트 외에도 단일 문자열이나 숫자또한 유효한 JSON 오브젝트가 된다.
  • 자바스크립트에서 오브젝트 속성이 따옴표로 묶이지 않을 수 있는 것과 달리, JSON에는
    따옴표로 묶인 문자열만이 속성으로 사용될 수 있다.

JSON을 다뤄보자

자바스크립트 코드를 담기위한 스크립트 요소를 추가하자.
header와 section요소를 참조하여 변수에 담는 코드이다.

<script>
var header = document.querySelector('header');
var section = document.querySelector('section');
</script>

아래는 JSON파일의 내용이다.

{
  "squadName" : "Super Hero Squad",
  "homeTown" : "Metro City",
  "formed" : 2016,
  "secretBase" : "Super tower",
  "active" : true,
  "members" : [
    {
      "name" : "Molecule Man",
      "age" : 29,
      "secretIdentity" : "Dan Jukes",
      "powers" : [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name" : "Madame Uppercut",
      "age" : 39,
      "secretIdentity" : "Jane Wilson",
      "powers" : [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name" : "Eternal Flame",
      "age" : 1000000,
      "secretIdentity" : "Unknown",
      "powers" : [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

JSON 가져오기

JSON을 가져오기 위해서는, XMLHttpRequest(XHL)로 불리는 API를 사용하면 된다.
이것은 매우 유용한 자바스크립트 객체로 자바스크립트를 통해 우리가 서버로부터
다양한 리소스를 가져오는 요청을 만들어준다. 즉, 전체 페이지를 불러오지 않고도 필요한
부분만을 업데이트 할 수 있다.

  1. 일단 변수로 둘 JSON의 URL을 가져와야한다.
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
  1. 요청을 만들기 위해, 우리는 new 키워드를 이용하여 XMLHttpRequest 생성자로부터
    새로운 request 인스턴스를 생성해야한다.
var request = new XMLHttpRequest();
  1. 이제 open() 메소드를 사용해 새로운 요청을 만듭니다.
request.open('GET', requestURL);

이것은 최소 두 개의 매개변수를 가지는데

  • HTTP 메소드는 네트워크 요청을 만들 때 사용된다. 그저 데이터를 가져올 때는 GET을 사용하면 된다.
  • URL은 요청을 보낼 곳을 지정한다. 우리가 저장해둔 JSON 파일의 URL로 지정하자.
  1. responseType을 JSON으로 설정하자. XHL로 하여금 서버가 JSON 데이터를 반환할 것이며,
    자바스크립트 객체로서 변환될 것이라는 것을 알게 하기 위해서이다. 그리고 send() 함수로 요청을 보내자.
request.responseType = 'json';
request.send();
  1. 마지막 부분은 서버의 응답을 기다리고, 그것의 처리까지에 대한 섹션이다.
request.onload = function() {
var superHeros = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);
}

우리는 요청에 대한 응답을 superHeroes라는 변수에 저장한다. 이 변수는 이제 JSON 데이터에 기반한
자바스크립트 객체를 포함하게 된다. 두 개의 함수를 호출해 이 객체를 전달하자.
하나는 header를 적절한 데이터로 채울 것이고, 다른 하나는 각 히어로에 대한 정보카드를 생성하여
section에 집어넣을 것이다.

HTML요소 조작하기

우리는 JSON 데이터를 가져왔고, 그것을 자바스크립트 객체로 변환했다.
이제 위에 언급한 두 개의 함수를 사용함으로써 이를 활용해보자.

function populateHeader(jsonObj) {
  var myH1 = document.createElement('h1');
  myH1.textContent = jsonObj['squadName'];
  header.appendChild(myH1);

  var myPara = document.createElement('p');
  myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed'];
  header.appendChild(myPara);
}

jsonObj 라는 매개변수는 우리가 이 자바스크립트 객체가 JSON으로부터 왔음을 상기시키기 위해 사용했다.
createElement() 요소로 HTML'h1' 요소를 생성하고 이것의 textContent를
객체의 squadName 속성과 같도록 만들어준 뒤, appendChild()를 사용해서 헤더에 붙이도록 했다.
비슷한 과정을 paragraph에도 적용하였다.

function showHeroes(jsonObj) {
  var heroes = jsonObj['members'];

  for (var i = 0; i < heroes.length; i++) {
    var myArticle = document.createElement('article');
    var myH2 = document.createElement('h2');
    var myPara1 = document.createElement('p');
    var myPara2 = document.createElement('p');
    var myPara3 = document.createElement('p');
    var myList = document.createElement('ul');

    myH2.textContent = heroes[i].name;
    myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
    myPara2.textContent = 'Age: ' + heroes[i].age;
    myPara3.textContent = 'Superpowers:';

    var superPowers = heroes[i].powers;
    for (var j = 0; j < superPowers.length; j++) {
      var listItem = document.createElement('li');
      listItem.textContent = superPowers[j];
      myList.appendChild(listItem);
    }

    myArticle.appendChild(myH2);
    myArticle.appendChild(myPara1);
    myArticle.appendChild(myPara2);
    myArticle.appendChild(myPara3);
    myArticle.appendChild(myList);

    section.appendChild(myArticle);
  }
}

우선, 새로운 변수에 자바스크립트 객체 내의 member 속성을 저장한다.
다음으로, for loop를 사용하여 배열 내의 각 객체에 반복 실행을한다.

객체와 문자 사이의 변환

위의 예제는 자바스크립트 객체에 접근한다는 관점에서 단순한 편이었다.
왜냐하면 자바스크립트 객체를 사용해 우리는 XHR 요청을 바로 JSON 응답으로 변환했기 때문이다

request.responseType = 'json';

하지만 우리는 이따금씩 날것의 JSON 문자열을 받기도 하고, 그것을 우리가 스스로 객체로
변환시켜야 할 때도 생긴다. 그리고 네트워크를 통해 자바스크립트 객체를 보내고 싶을 때도
우리는 전송 전에 그걸 JSON(문자열)로 변환시켜야한다. 다행히도, 이 두가지 문제가 웹 개발에
있어서 매우 흔한 덕에 다음과 같은 두가지 방법을 포함한 JSON 내장 객체가 브라우저 내에서
이용 가능하다.

  • parse(): JSON 문자열을 매개변수로서 수용하고, 일치하는 자바스크립트 객체로서 변환한다.
  • stringify(): 객체를 매개변수로서 수용하고, JSON 문자열 형태로 변환한다.
request.open('GET', requestURL);
request.responseType = 'text'; // now we're getting a string!
request.send();

request.onload = function() {
  var superHeroesText = request.response; // get the string from the response
  var superHeroes = JSON.parse(superHeroesText); // convert it to an object
  populateHeader(superHeroes);
  showHeroes(superHeroes);
}

위에서 작성했던 코드를 parse()함수를 넣은 버전이다.

0개의 댓글

관련 채용 정보