동기식 처리 모델
비동기식 처리 모델
브라우저는 XMLHttpRequest 객체를 이용해서 Ajax 요청을 생성한다.
서버가 브라우저 요청에 대한 응답 반환 시 동일한 XMLHttpRequest 객체가 결과를 처리한다.
Ajax 요청 처리 예
// 1. XMLHttpRequest 객체 생성 -> Ajax 요청 생성
var request = new XMLHttpRequest();
// 비동기 방식으로 Request 오픈
request.open('GET', 'data/test.json', true);
//XMLHttpRequest.send()를 통해 서버에 Request 전송 => 서버는 Response를 반환
request.send();
Ajax 응답 처리 예
// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 XMLHttpRequest.onreadystatechange라는 콜백함수(이벤트 핸들러) 호출.
// Response가 클라이언트에 도달 시 호출된다.
request.onreadystatechange = function(e){
// readyStates는 XMLHttpRequest의 상태(state) 반환
// readyState == 4 : DONE(서버 응답 완료)
if(request.readyState === XMLHttpRequest.DONE){
// status는 response 상태 코드 반환
// 200 : 정상응답
if(request.status == 200){
console.log(request.responseText);
}else{
console.log("Error!");
}
}
};
XMLHttpRequest.send()로 서버에 Request를 보내면, 서버는 Response를 반환한다.
XMLHttpRequest.onreadystatechange
XMLHttpRequest.responseText
$ git clone https://github.com/ungmo2/webserver-express.git
$ cd webserver-express
$ npm i // install dependencies
$ mkdir public // working directory (root directory)
$ cd public
위의 과정으로 express 웹서버 세팅을 했고, public이라는 디렉터리가 작업 디렉터리로, 여기에서 파일을 생성한다.
webserver-express 디렉터리에서
$ npm start
위의 명령어를 입력하면 웹서버를 실행하면 3000번 포트에서 포트를 열어서 서버가 listening을 하고 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Example document</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>
http://localhost:3000/exam.html 으로 접속 시 페이지가 정상적으로 로드되어 실행되는 것을 확인할 수 있다.
<!-- public/loadhtml.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script>
// XMLHttpRequest 객체 생성 - Ajax 요청 생성
var request = new XMLHttpRequest();
// Request 오픈 (비동기 방식)
request.open('GET', 'data/data.html', true)
// Request를 서버에게 전송
request.send();
request.onreadystatechange = function(e){
// 서버 응답이 완료됐고,
if(request.readyState === XMLHttpRequest.DONE){
// 정상 응답이면
if(request.status == 200){
console.log(request.responseText);
document.getElementById('content').innerHTML = request.reseponseText;
}else{
console.log('[' + request.status + ']: ' + request.statusText);
}
}
};
</script>
</body>
</html>
<!-- public/data/data.html -->
<div id="tours">
<h1>Guided Tours</h1>
<ul>
<li class="usa tour">
<h2>New York, USA</h2>
<span class="details">$1,899 for 7 nights</span>
<button class="book">Book Now</button>
</li>
<li class="europe tour">
<h2>Paris, France</h2>
<span class="details">$2,299 for 7 nights</span>
<button class="book">Book Now</button>
</li>
<li class="asia tour">
<h2>Tokyo, Japan</h2>
<span class="details">$3,799 for 7 nights</span>
<button class="book">Book Now</button>
</li>
</ul>
</div>
서버에서 브라우저로 전송된 JSON 데이터 == 문자열
역직렬화(Deserializing)
<-- public/loadjson.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script>
// XMLHttpRequest 객체의 생성
var 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
var newContent = '';
newContent += '<div id="tours">';
newContent += '<h1>Guided Tours</h1>';
newContent += '<ul>';
for (var 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);
}
}
};
</script>
</body>
</html>
// public/data/data.json
{
"tours": [
{
"region": "usa",
"location": "New York, USA",
"details": "$1,899 for 7 nights"
},
{
"region": "europe",
"location": "Paris, France",
"details": "$2,299 for 7 nights"
},
{
"region": "asia",
"location": "Tokyo, Japan",
"details": "$3,799 for 7 nights"
}
]
}
loadjson.html 에서 data.json 파일을 열어서, String인 JSON 데이터를 JSON,parse()를 통해 responseObject라는 Object로 역직렬화했다.
이후 이 responseObject 객체를 통해 tours 내 각 region 키에서 value를 가져와 <li> 태그의 클래스 이름을 순차적으로 usa tour, europe tour, asia tour로 만드는 등 HTML String으로 구조화한다.
document.getElementById('content').innerHTML = newContent; 로 만든 HTML String을 content라는 아이디 가진 태그 내의 innerHTML으로 넣는다.
동일출처원칙(Same-origin policy)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id='content'></div>
<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;
}
</script>
<script src='http://poiemaweb.com/assets/data/data-jsonp.js'></script>
</body>
</html>
https://poiemaweb.com/assets/data/data-jsonp.js
showTours({
"tours": [
{
"region": "usa",
"location": "New York, USA",
"details": "$1,899 for 7 nights"
},
{
"region": "europe",
"location": "Paris, France",
"details": "$2,299 for 7 nights"
},
{
"region": "asia",
"location": "Tokyo, Japan",
"details": "$3,799 for 7 nights"
}
]
});
jQuery.ajax( url [, settings ] ) // Returns: jqXHR
jQuery.ajax( [settings ] ) // Returns: jqXHR
settings : Ajax 요청 설정 정보, key/value 쌍으로 이루어진 객체. 옵션으로 사용한다.
1-1. Load HTML
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id='content'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.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);
})
</script>
</body>
</html>
1-2. Load JSON
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id='content'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.ajax({
url: "data/data.json",
dataType: "json"
})
.done(function(data){
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>';
newContent += '</div>';
$("#content").html(newContent);
})
.fail(function(jqXHR, textStatus, errorThrown){
console.log("fail: ", jqXHR);
})
.always(function(data, textStatus, jqXHR){
console.log("always: ", data);
})
</script>
</body>
</html>
1-3. Load JSONP
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.ajax({
url: "http://poiemaweb.com/assets/data/data-jsonp.js",
dataType: "jsonp",
jsonpCallback: "showTours"
})
.done(function(data, textStatus, jqXHR){
console.log("done: ", data);
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>';
$('#content').html(newContent);
})
.fail(function(jqXHR, textStatus, errorThrown){
console.log("fail: ", jqXHR);
})
.always(function(data, textStatus, jqXHR){
console.log("always: ", data);
})
</script>
</body>
</html>
2-1. jQuery.get()
jQuery.get( url [, data ] [, success ] [, dataType ] ) // Returns: jqXHR
HTTP GET 요청으로 서버로부터 데이터 로드한다.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.get("data/data.html", function(data){
$('#content').html(data);
});
</script>
</body>
</html>
2-2. jQuery.getJSON()
jQuery.getJSON( url [, data ] [, success ] ) // Returns: jqXHR
HTTP GET 요청을 통해 서버로부터 JSON encoded 데이터를 로드한다.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$.getJSON("data/data.json", function(data){
var content = '';
content += '<div id="tours">';
content += '<h1>Guided Tours</h1>';
content += '<ul>';
for (var i = 0; i < data.tours.length; i++) {
content += '<li class="' + data.tours[i].region + ' tour">';
content += '<h2>' + data.tours[i].location + '</h2>';
content += '<span class="details">' + data.tours[i].details + '</span>';
content += '<button class="book">Book Now</button>';
content += '</li>';
}
content += '</ul></div>';
$('#content').html(content);
});
</script>
</body>
</html>
2-3. jQuery.getScript()
jQuery.getScript( url [, success ] ) // Returns: jqXHR
HTTP GET 요청을 통해 서버로부터 JavaScript 파일을 로드한 후 실행한다.
2-4. JQuery.post()
jQuery.post( url [, data ] [, success ] [, dataType ] ) // Returns: jqXHR
서버로부터 데이터를 로드한다.
2-5. load()
.load( url [, data ] [, complete ] ) // Returns: jQuery
서버로부터 HTML 데이터 로드 후 Matched set에 적용한다.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link rel="stylesheet" href="http://poiemaweb.com/assets/css/ajax.css">
</head>
<body>
<div id="content"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$('#content').load("data/data.html", function(){
console.log("Load performed.");
})
</script>
</body>
</html>
Fetch API 통한 Ajax 구현 #2 (0) | 2021.02.24 |
---|---|
Fetch API 통한 Ajax 구현 #1 (0) | 2021.02.24 |
[Web 개발] Day and Night Mode #2 (jQuery, Bootstrap) (0) | 2021.02.19 |
jQuery #1 (0) | 2021.02.18 |
[Web 개발] Day and Night Mode #1 (jQuery, Bootstrap) (0) | 2021.02.02 |