본문 바로가기
Today I learned

Ajax & Javascript 정리

by soheemon 2019. 1. 21.


링크를 참고하여 작성했습니다.


* JavaScript Object와 JSON


//Array와 Object를 선언 후 console로 출력해 본다.


<!-- html -->


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

<script src="intro.js"></script>

</head>

<body>

 

</body>

</html>

 

/**

 * intro.js

 */

var springColors = ["AF7575", "EFDBA1", "BCD693", "AFD7DB", "3D9CAB"];

var tempreatures = [47.5, 63.2, 56.7, 53, 51.2];

var pickles = {

               type: "cat",

               name: "Pickles",

               weight: 7

};

window.onload = init;

function init() {

        console.log(springColors);

        console.log(tempratures);

        console.log(pickles);

}


// 결과


서버로부터 데이터를 받을때 데이터가 어떤포맷인지 알아야 한다. 단순히 text일수도 있고, CSV 파일일수도 있고 XML파일일수도 있다.

JSON은 Object나, Array도 표현 할 수 있고, Object안에 Array가 있더라도 표현 할 수 있다.


var pickles = {

               type: "cat",

               name: "Pickles",

               weight: 7,

               likes: ["sleeping", "purring", "eating butter"] // Object에 linkes라는 Array추가!

};


//결과



//지금까지는 객체를, {}를 사용하는방식으로 생성했지만, 만약 생성해야 하는 객체가 많아지면.. 이 방법만으로는 작성하기가 어려울것이다.

그래서 생성자를 사용한다. 생성자를 사용해서 객체를 생성 후 출력해보자.


/**

 *

 */

function Pet(type, name, weight, likes){ // 생성자

        this.type = type;

        this.name = name;

        this.weight = weight;

        this.likes = likes;

}

 

window.onload = init;

function init() {

        var pickles = new Pet("cat", "Pickles", 7, ["sleeping", "purring", "eating butter"]); //new로 생성자 사용

        var poppy = new Pet("dog", "Poppy", 25, ["sleeping", "eat EveryTing", "walking"]);

        console.log(pickles);

        console.log(poppy);

}


//출력 결과. {}를 사용해서 객체를 생성하는 방식과 결과가 같다는것을 알 수 있다.




//JavaScript Object를 JSON으로 변환해보자. stringify()라는 메서드를 사용한다.

stringify()는 JSON객체의 method이며, JavaScript객체를 인자로 받아서 JSON version 객체를 반환해준다.

=> Object Array도 JSON으로 변환 가능하다 !

JSON이 가장 큰 장점은 JSON-formatted 객체가 문자열이라는 사실이다!. 그래서 파일로 저장할 수 있다.

(.json파일을 열었을때나, console에서 JSON객체를 찍어봤을때나 같음!)

/**

 *

 */

function Pet(type, name, weight, likes){

        this.type = type;

        this.name = name;

        this.weight = weight;

        this.likes = likes;

}

 

window.onload = init;

function init() {

        var pickles = new Pet("cat", "Pickles", 7, ["sleeping", "purring", "eating butter"]);

        var poppy = new Pet("dog", "Poppy", 25, ["sleeping", "eat EveryTing", "walking"]);

        console.log(pickles);

        console.log(poppy);

       

        var petsArray = [poppy, pickles]; //Pet객체를 Array 만든다.

        var petsArrayJSON = JSON.stringify(petsArray); //JavaScript Array JSON으로 변환 가능!

        console.log(petsArrayJSON);

}



Object를 String으로 변환하는것은 직렬화(Serializing)로 알려져 있다.

(Object를 text file로 저장하거나 Web App 주고받을 수 있다는것은 유용하다)

다른 언어를 사용하더라도 데이터를 주고 받을 수 있기 때문이다. 


//JSON으로 표현된 객체를 받았을때. 어떻게 JAVASCRIPT에서 사용 가능한 객체로 만들까? => Deserializing(역직렬화) 한다.

=> JSON객체의 parse메서드를 사용한다.


        var pickles = new Pet("cat", "Pickles", 7, ["sleeping", "purring", "eating butter"]);

        var pickleJSON = JSON.stringify(pickles); // 직렬화

        console.log("pickleJSON:" + pickleJSON);

       

        var anotherPickles = JSON.parse(pickleJSON); // 역직렬화

        console.log(anotherPickles);

        


//결과. JSON String이랑, JSON String으로 파싱되어진 Javascript 객체를 볼 수 있다.

 


*AJAX

//서버로부터 JSON파일을 받아와서 div내에 출력하는 예제.


<!doctype html>

<html>

<head>

<title>Your First Ajax Application: Pets</title>

<meta charset="utf-8">

<script src="pets.js"></script>

<style>

body {

        font-family: Helvetica, Arial, sans-serif;

}

 

legend {

        font-weight: bold;

}

</style>

</head>

<body>

        <div>

               <fieldset>

                       <legend>Pets available for adoption</legend>

                       <div id="pets"></div>

               </fieldset>

        </div>

</body>

</html>

 



//XMLHttpRequest 객체를 생성하여 변수 request에 넣는다. XMLHttpRequest객체는 request를 생성할 수 있는 propertie와 method를 가지고 있다.

서버로부터 pets.json 파일을 요청해서 html로 가져오는 예제.

//open메서드는 실제로 request를 보내지 않는다. send메서드가 실제로 보낸다.


//Ready State 참고


window.onload = init;

function init() {

        getPetData();

}

function getPetData() {

        var request = new XMLHttpRequest();

        request.open("GET", "pets.json"); // default: true(Async), false(Sync)

        request.onreadystatechange = function() { //callback function!

               var div = document.getElementById("pets");

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText != null) {

                              div.innerHTML = this.responseText;

                       } else {

                              div.innerHTML = "Error: no data";

                       }

               }

        };

        request.send();

}

 




[

        {

               "type": "cat",

               "name": "Pickles",

               "weight": 7,

               "likes": [

                       "sleeping",

                       "purring",

                       "eating butter"

               ]

        },

        {

               "type": "dog",

               "name": "Tilla",

               "weight": 25,

               "likes": [

                       "sleeping",

                       "eating",

                       "walking"

               ]

        }

]

 


//결과


 


//디버깅! contents 타입과 header. 찍어 볼 수 있다.

var type = request.getResponseHeader("Content-Type"); 

console.log("Content-type: " + type);

console.log("Status: " + this.statusText);


* JavaScript & AJAX & JSP를 이용한 간단한 Project - TO-DO LIST


<!doctype html>

<html>

        <head>

               <title>To-Do List</title>

               <meta charset="utf-8">

               <script src="todo.js"></script>

               <style>

               body {

                       font-family: Helvetica, Arial, sans-serif;

               }

               </style>

        </head>

        <body>

               <h1>My To-Do List</h1>

               <div id="todoList"></div>

        </body>

</html>



//단순히 responseText를 출력하면 JSON String이 표시된다.


window.onload = init;

function init() {

        getTodoData();

}

function getTodoData() {

        var request = new XMLHttpRequest();

        request.open("GET", "todo.json");

        request.onreadystatechange = function() {

               var listDiv = document.getElementById("todoList");

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText) {

                              listDiv.innerHTML = this.responseText;

                       } else {

                              console.log("Error: Data is empty");

                       }

               }

        };

        request.send();

}


[

        {

               "task": "get milk",

               "who": "Scott",

               "dueDate": "today",

               "done": false

        },

        {

               "task": "get broccoli",

               "who": "Elisabeth",

               "dueDate": "today",

               "done": false

        }

]



//실행결과



To-Do Object를 만들어 보자.

우선 서버로부터 To-Do list 데이터를 받아 왔다.

이것을 JAVAScript에서 활용하기 위해서는 JAVAScript 객체로 만들어야 겠지.

그때는 JSON.parse()메서드를 사용하면 된다.


마찬가지로 서버에 JSON데이터로 전송하기 위해서는, JSON.stringify()메서드를 사용하면 된다.


+서버로부터 받은 JSON String을 JavaScript 객체로 변경해보자.

서버는 여러개의 JSON String을 넘겨 줄 수 있다. 즉, JSON.parse(todoJSON)의 결과는 Array일 수 있음!

이것을 하나 하나 받아와서 todos라는 전역변수(배열)에 push 해주자. 그러면 최종적으로 서버가 보낸 TodoList가 JavaScript 객체배열이 된다.


var todos = new Array();

 

window.onload = init;

function init() {

        getTodoData();

}

function getTodoData() {

        var request = new XMLHttpRequest();

        request.open("GET", "todo.json");

        request.onreadystatechange = function() {

               //var listDiv = document.getElementById("todoList");

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText) {

 parseTodoItems(this.responseText);

                              //listDiv.innerHTML = this.responseText;

                       } else {

                              console.log("Error: Data is empty");

                       }

               }

        };

        request.send();

}

 

function parseTodoItems(todoJSON) {

        if (todoJSON == null || todoJSON.trim() == "") {

               return;

        }

        var todoArray = JSON.parse(todoJSON); // 서버로부터 받은 JSON String 파싱하여 JavaScript 객체로 생성


        if(todoArray.length == 0) {

               console.log("error: the to-do list Array is empty!");

               return;

        }


        for(var i = 0; i < todoArray.length; i++) {

               var todoItem = todoArray[i];

               todos.push(todoItem);

        }

        console.log("To-do array: ");

        console.log(todos);

}



//실행 결과




자, 이제 JavaScript객체로 전환했으니 단순 String을 보여주지 말고,

List형식으로 바꿔서 보여주자.

코드를 아래와 같이 변경하쟈.


<!doctype html>

<html>

        <head>

               <title>To-Do List</title>

               <meta charset="utf-8">

               <script src="todo.js"></script>

               <style>

               body {

                       font-family: Helvetica, Arial, sans-serif;

               }

               </style>

        </head>

        <body>

               <h1>My To-Do List</h1>

               <ul id="todoList"></ul>

        </body>

</html>

 



//JavaScript객체니까 당연히 .으로 필드에 접근이 가능하지.

단순히 innerHTML으로 div에 넣어줬던거에서,

Todo리스트의 객체 수만큼, createElement로 li element를 생성해서 화면에 뿌려주자!

 

var todos = new Array();

 

window.onload = init;

function init() {

        getTodoData();

}

function getTodoData() {

        var request = new XMLHttpRequest();

        request.open("GET", "todo.json");

        request.onreadystatechange = function() {

               //var listDiv = document.getElementById("todoList");

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText) {

                              //listDiv.innerHTML = this.responseText;

                              parseTodoItems(this.responseText);

                              addTodosToPage();

                       } else {

                              console.log("Error: Data is empty");

                       }

               }

        };

        request.send();

}

 

function parseTodoItems(todoJSON) {

        if (todoJSON == null || todoJSON.trim() =="") {

               return;

        }

        var todoArray = JSON.parse(todoJSON);

        if(todoArray.length == 0) {

               console.log("error: the to-do list Array is empty!");

               return;

        }

        for(var i = 0; i < todoArray.length; i++) {

               var todoItem = todoArray[i];

               todos.push(todoItem);

        }

        console.log("To-do array: ");

        console.log(todos);

}

 

function addTodosToPage() {

        var ul = document.getElementById("todoList");

        for(var i = 0; i < todos.length; i++) {

               var todoItem = todos[i];

               var li = document.createElement("li");

               li.innerHTML =

                       todoItem.who + " needs to " + todoItem.task + " by " + todoItem.dueDate;

               ul.appendChild(li);

        }

}


//실행 결과



지금까지는 서버의 JSON파일을 불러와야 했다.

이제는 form을 이용해서 ToDo List를 입력해보자.


body {

        font-family: Helvetica, Arial, sans-serif;

}

 

legend {

        font-weight: bold;

}

 

div.tableContainer {

        display: table;

        border-spacing: 5px;

}

 

div.tableRow {

        display: table-row;

}

 

div.tableRow label {

        display: table-cell;

        text-align: right;

}

 

div.tableRow input {

        display: table-cell;

}


<!doctype html>

<html>

<head>

<title>To-Do List</title>

<meta charset="utf-8">

<script src="todo.js"></script>

 

<link rel="stylesheet" href="todo.css">

</head>

<body>

        <h1>My To-Do List</h1>

        <ul id="todoList">

        </ul>

        <form>

               <fieldset>

                       <legend>Add a new to-do item</legend>

                       <div class="tableContainer">

                              <div class="tableRow">

                                      <label for="task">Task: </label> <input type="text" id="task"

                                              size="35" placeholder="get milk">

                              </div>

                              <div class="tableRow">

                                      <label for="who">Who should do it: </label> <input type="text"

                                              id="who" placeholder="Scott">

                              </div>

                              <div class="tableRow">

                                      <label for="dueDate">Due Date: </label> <input type="date"

                                              id="dueDate">

                              </div>

                              <div class="tableRow">

                                      <label for="submit"></label> <input type="button" id="submit"

                                              value="submit">

                              </div>

                       </div>

               </fieldset>

        </form>

</body>

</html>



//버튼클릭 이벤트 핸들러로 getFormData를 등록한다. (예외처리 목적) = init시 실행되는것이 아니라 이벤트가 발생하면 실행된다 !

그리고 서버로부터 데이터를 가져오는것은 같다.


var todos = new Array();

 

window.onload = init;

function init() {

        var submitButton = document.getElementById("submit");

        submitButton.onclick = getFormData;

        getTodoData();

}

function getTodoData() {

        var request = new XMLHttpRequest();

        request.open("GET", "todo.json");

       

        request.onreadystatechange = function() {

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText) {

                              parseTodoItems(this.responseText);

                              addTodosToPage();

                       } else {

                              console.log("Error: Data is empty");

                       }

               }

        };

        request.send();

}

 

function parseTodoItems(todoJSON) {

        if (todoJSON == null || todoJSON.trim() =="") {

               return;

        }

        var todoArray = JSON.parse(todoJSON);

        if(todoArray.length == 0) {

               console.log("error: the to-do list Array is empty!");

               return;

        }

        for(var i = 0; i < todoArray.length; i++) {

               var todoItem = todoArray[i];

               todos.push(todoItem);

        }

        console.log("To-do array: ");

        console.log(todos);

}

 

function addTodosToPage() {

        var ul = document.getElementById("todoList");

        for(var i = 0; i < todos.length; i++) {

               var todoItem = todos[i];

               var li = document.createElement("li");

               li.innerHTML =

                       todoItem.who + " needs to " + todoItem.task + " by " + todoItem.dueDate;

               ul.appendChild(li);

        }

}

 

function getFormData() {

        var task = document.getElementById("task").value;

        if(checkInputText(task, "Please enter a task")) return;

       

        var who = document.getElementById("who").value;

        if(checkInputText(who, "Please Enter a person to do the task")) return;

       

        var date = document.getElementById("dueDate").value;

        if(checkInputText(date, "Please enter a due date")) return;

       

        console.log("New task: " + task +", for: " + who + ", by: " + date);

}

 

function checkInputText(value, msg) {

        if(value == null || value == "") {

               alert(msg);

               return true;

        }

        return false;

}


//결과

데이터를 전부 입력하면(예외처리로 빠지지 않으면) console에 사용자가 입력한 내용이 출력된다!


하지만.. 입력한 데이터가 TodoList로 들어가서 화면에 목록으로 출력되려면 어떻게 해야할까..


TodoList 생성자 함수 생성 및 사용자가 입력한 내용을 Todo객체로 만들어 

전역변수(TodoList 배열)에 추가하기


function Todo(task, who, DueDate) {

        this.task = task;

        this.who = who;

        this.dueDate = dueDate;

        this.done = false;

}

 

var todos = new Array();

 

window.onload = init;

function init() {

        var submitButton = document.getElementById("submit");

        submitButton.onclick = getFormData;

        getTodoData();

}

function getTodoData() {

        var request = new XMLHttpRequest();

        request.open("GET", "todo.json");

       

        request.onreadystatechange = function() {

               if (this.readyState == this.DONE && this.status == 200) {

                       if (this.responseText) {

                              parseTodoItems(this.responseText);

                              addTodosToPage();

                       } else {

                              console.log("Error: Data is empty");

                       }

               }

        };

        request.send();

}

 

function parseTodoItems(todoJSON) {

        if (todoJSON == null || todoJSON.trim() =="") {

               return;

        }

        var todoArray = JSON.parse(todoJSON);

        if(todoArray.length == 0) {

               console.log("error: the to-do list Array is empty!");

               return;

        }

        for(var i = 0; i < todoArray.length; i++) {

               var todoItem = todoArray[i];

               todos.push(todoItem);

        }

        console.log("To-do array: ");

        console.log(todos);

}

 

function addTodosToPage() {

        var ul = document.getElementById("todoList");

        for(var i = 0; i < todos.length; i++) {

               var todoItem = todos[i];

               var li = document.createElement("li");

               li.innerHTML =

                       todoItem.who + " needs to " + todoItem.task + " by " + todoItem.dueDate;

               ul.appendChild(li);

        }

}

 

function getFormData() {

        var task = document.getElementById("task").value;

        if(checkInputText(task, "Please enter a task")) return;

       

        var who = document.getElementById("who").value;

        if(checkInputText(who, "Please Enter a person to do the task")) return;

       

        var date = document.getElementById("dueDate").value;

        if(checkInputText(date, "Please enter a due date")) return;

       

        console.log("New task: " + task +", for: " + who + ", by: " + date);

        var todoItem = new Todo(task, who, date);

        todos.push(todoItem);

}

 

function checkInputText(value, msg) {

        if(value == null || value == "") {

               alert(msg);

               return true;

        }

        return false;

}

 

 


//실행 결과

//Form에 입력한 내용이 객체로 생성되어 List에 들어가 있는것을 볼 수 있다.



Console로 확인한 내용을 화면에 출력하기


//새로 추가한 Toto는 현재 list에만 들어가 있는 상태다.

사용자도 볼 수 있도록 페이지에도 출력 해보자.

//전역변수 list에 사용자가 Form에 입력한 내용을 토대로 새로운 todoItem을 추가 한 후,

화면에 출력해준다.

function getFormData() {

        var task = document.getElementById("task").value;

        if(checkInputText(task, "Please enter a task")) return;

       

        var who = document.getElementById("who").value;

        if(checkInputText(who, "Please Enter a person to do the task")) return;

       

        var date = document.getElementById("dueDate").value;

        if(checkInputText(date, "Please enter a due date")) return;

       

        console.log("New task: " + task +", for: " + who + ", by: " + date);

        var todoItem = new Todo(task, who, date);

        todos.push(todoItem);

        addTodoToPage(todoItem); //getFormData함수에서 호출

}


//ul을 불러와서.. li노드를 하나 만든 후... innerHTML을 이용해서 내용을 입력 해 준다.

//그리고 ul에 자식노드로 붙여준다.

//그리고 Form에 입력된 내용을 비우기 위해서 docuemnt.forms[0].reset()을 해준다.!

function addTodoToPage(todoItem) {

        var ul = document.getElementById("todoList");

        var li = document.createElement("li");

       

        li.innerHTML =

               todoItem.who + " needs to " + todoItem.task + " by " + todoItem.dueDate;

        ul.appendChild(li);

        document.forms[0].reset();

}


//하지만 위 방법은 웹브라우저에 저장되기 때문에, 새로고침한다면.. 새로입력한 내용이 사라지게 된다!

따라서 서버에 저장하고, window init시 웹브라우저로 가져올 필요가 있다.


브라우저에서 저장한 내용을 서버에 저장하기.

function getFormData() {

        var task = document.getElementById("task").value;

        if(checkInputText(task, "Please enter a task")) return;

       

        var who = document.getElementById("who").value;

        if(checkInputText(who, "Please Enter a person to do the task")) return;

       

        var date = document.getElementById("dueDate").value;

        if(checkInputText(date, "Please enter a due date")) return;

       

        console.log("New task: " + task +", for: " + who + ", by: " + date);

        var todoItem = new Todo(task, who, date);

        todos.push(todoItem);

        addTodoToPage(todoItem);

        saveTodoDate();//서버에 URI뒤에 파라미터로 전송한다.

}


//JSON형식의 String으로 변환 후, 데이터를 URI뒤에 붙여서 전송한다.(URI인코딩 필요!)

function saveTodoDate() {

        var todoJSON = JSON.stringfy(todos);//자바스크립트 객체르 JSONString으로

        var request = new XMLHttpRequest();

        var URL = "save.jsp?data=" + encodeURI(todoJSON);

        request.open("GET", URL);

        request.setRequestHeader("Content-Type",

                       "text/plain;charsete=UTF-8");

        request.send();

}


//request를 살펴보면 이런 모양이 된다..

 


Document Fragments

페이지에 새로운 elements를 추가하는 효율적인 방법은 document fragments를 사용하는 것이다.


//Document Fragments를 사용해서 페이지에 새로운 elements를 추가하기.

Document Fragments는 DOM트리로부터 분리되어있다.

(DOM트리에 한번에 추가하면 부하를 발생하기 때문에, DocumentFragment를 생성후 tree를 구성해서 마지막으로 그것을 DOM Tree에 붙이는듯)


간단한 예제로 이해해 보자.


<!doctype html>

<html>

<head>

<title>Document Fragments</title>

<meta charset="utf-8">

<script src="frag.js"></script>

<style>

div.box {

        position: relative;

        width: 100px;

        height: 100px;

}

</style>

</head>

<body>

        <div id="container"></div>

</body>

</html>


//앞서 우리가 사용했었던 방법과 일치한다.

DOMTree에 이미 존재하는 div를 가져와서(container), 

새로운 div element를 생성후,

기존의 div에 붙여주는 코드이다.

=앞서 설명했던것처럼 이 방법은 DOM에 '직접' element를 추가하기 때문에 반복할 수록 부하를 발생하게 된다.


window.onload = init;

function init() {

        var colors = [ "red", "blue", "green" ];

        var container = document.getElementById("container");

        for (var i = 0; i < 3; i++) {

               var box = document.createElement("div");

               box.setAttribute("class", "box");

               box.style.backgroundColor = colors[i];

               container.appendChild(box);

        }

}


이미지로 보면 이런 모습이다.


//fragment사용해서 만들어보자.



Lesson 6: Document Fragment 할차례임.



























댓글