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에서 유효하기 때문이다.
[
{
"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이다. 배열의 요소에 접근하기 위해서는 배열의 인덱스를 사용하면 된다.
자바스크립트 코드를 담기위한 스크립트 요소를 추가하자.
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을 가져오기 위해서는, XMLHttpRequest(XHL)로 불리는 API를 사용하면 된다.
이것은 매우 유용한 자바스크립트 객체로 자바스크립트를 통해 우리가 서버로부터
다양한 리소스를 가져오는 요청을 만들어준다. 즉, 전체 페이지를 불러오지 않고도 필요한
부분만을 업데이트 할 수 있다.
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
var request = new XMLHttpRequest();
request.open('GET', requestURL);
이것은 최소 두 개의 매개변수를 가지는데
request.responseType = 'json';
request.send();
request.onload = function() {
var superHeros = request.response;
populateHeader(superHeroes);
showHeroes(superHeroes);
}
우리는 요청에 대한 응답을 superHeroes라는 변수에 저장한다. 이 변수는 이제 JSON 데이터에 기반한
자바스크립트 객체를 포함하게 된다. 두 개의 함수를 호출해 이 객체를 전달하자.
하나는 header를 적절한 데이터로 채울 것이고, 다른 하나는 각 히어로에 대한 정보카드를 생성하여
section에 집어넣을 것이다.
우리는 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 내장 객체가 브라우저 내에서
이용 가능하다.
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()함수를 넣은 버전이다.