<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
// 성공 : BeforeSend -> success -> complete
// 실패 : BeforeSend -> error -> complete
function reqList(){
$.ajax({
url : "/Contact/list.do",
type : "GET",
data : {pageno:5, pagesize:5},
beforeSend : function(xhr, settings){
console.log("Before Send");
},
success : function(data){
console.log("success");
$("#resp").html(data);
},
error : function(xhr, status, error){
console.log("error : " + status + ", " + error);
},
complete : function(xhr, status){
console.log("complete");
}
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
// list_long.do는 2초 후에 응답처리
// timeout은 1.9초면 더 기다리지 않고 timeout처리
function reqList(){
$.ajax({
url : "/Contact/list_long.do",
type : "GET",
timeout : 1900,
data : {pageno:5, pagesize:5},
beforeSend : function(xhr, settings){
console.log("Before Send");
},
success : function(data){
console.log("success");
$("#resp").html(data);
},
error : function(xhr, status, error){
console.log("error : " + status + ", " + error);
},
complete : function(xhr, status){
console.log("complete");
}
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
get_post.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
/*
$.ajax() 함수를 대신해서 사용할 수 있는 단축 함수
1) $.get() : GET 요청
2) $.post() : POST 요청
*/
function reqList0(){
$.get("/Contact/list.do", function(data){
$("#resp").html(data);
});
}
function reqList1(){
var param = {};
param.name = "트와이스";
param.tel = "010-0000-2222";
param.address = "충남";
$.post("/Contact/add.do", param, function(data){
$("#resp").html(data);
});
}
function reqList2(){
$.get({
url : "/Contact/list_long.do",
data : {pageno:2, pagesize:5},
timeout : 1900,
success : function(data){
$("#resp").html(data);
},
error : function(xhr, status, error){
$("#resp").html(status + ", " + error);
}
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList0();">get 요청-0</button>
<button type="button" onclick="reqList1();">post 요청-1</button>
<button type="button" onclick="reqList2();">get 요청-2</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
get요청-2 결과
jqXHR.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
function reqList(){
var jqXHR = $.ajax({
url : "/Contact/list_long.do",
type : "GET",
data : {pageno:2, pagesize:5}
});
// success
jqXHR.done(function(data, status, xhr){
console.log("done");
console.log(data);
});
// error
jqXHR.fail(function(data, status, eror){
console.log("fail");
console.log(status + ", " + error);
});
// complete
jqXHR.always(function(){
console.log("always");
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
ajaxGET_Sync.html
: 좋은 방법은 아니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
/*
* 아래처럼 순서대로 요청하는 방법은 응답이 올때까지
계속 $.ajax()함수가 대기하게 되므로
결국 reqList()함수도 계속 리턴하지 못하고 대기에 들어간다.
그런데 이 상황에서 사용자의 이벤트가 발생하면 main thread는
$.ajax()에 의해 대기되므로 화면이 정지하거나
불안정한 상태가 되어 브라우저가 꺼지기도 한다.
그래서 deprecated라고 표시된다.
*/*/
function reqList(){
console.log("1 page 요청");
$.ajax({
url:"/Contact/list_long.do",
type:"GET",
async:false, // 동기
data:{pageno:1, pagesize:5},
success:function(data){
console.log("1 page 응답");
console.log(data);
$("#resp").html(data);
}
});
console.log("2 page 요청");
$.ajax({
url:"/Contact/list.do",
type:"GET",
async:false, // 동기
data:{pageno:2, pagesize:5},
success:function(data){
console.log("2 page 응답");
console.log(data);
$("#resp").html(data);
}
});
console.log("3 page 요청");
$.ajax({
url:"/Contact/list.do",
type:"GET",
async:false, // 동기
data:{pageno:3, pagesize:5},
success:function(data){
console.log("3 page 응답");
console.log(data);
$("#resp").html(data);
}
});
}
function delList(){
$("#resp").html("");
}
function sleep(ms) {
return new Promise(resolve=>setTimeout(resolve, ms));
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
callbackHell.html
콜백 동기
: 너무 많아지면 안좋다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
// 아래처럼 순서를 동기화하면
// 보내야 하는 요청이 많을 때
// 콜백안에서 계속 다시 요청해야 하므로 코드의 가독성이 매우 떨어지게 된다.
function reqList(){
console.log("Send Page1");
$.get("/Contact/list_long.do", {pageno:1}, function(data){
console.log("page1 success : " + (new Date()).toLocaleTimeString());
console.log(data);
console.log("Send Page2");
$.get("/Contact/list_long.do", {pageno:2}, function(data){
console.log("page2 success : " + (new Date()).toLocaleTimeString());
console.log(data);
console.log("Send Page3");
$.get("/Contact/list_long.do", {pageno:3}, function(data){
console.log("page3 success : " + (new Date()).toLocaleTimeString());
console.log(data);
});
});
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
callbackAsync.html
콜백 비동기
: 일단 요청이 응답과 상관없이 모두 실행이 되므로 빨리 끝나는 것을 먼저 응답해주기 때문에 순서대로 실행완료 할 수가 없다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
function reqList(){
console.log("Send Page1");
$.get("/Contact/list_long.do", {pageno:1}, function(data){
console.log("page1 success : " + (new Date()).toLocaleTimeString());
console.log(data);
});
console.log("Send Page2");
$.get("/Contact/list_long.do", {pageno:2}, function(data){
console.log("page2 success : " + (new Date()).toLocaleTimeString());
console.log(data);
});
console.log("Send Page3");
$.get("/Contact/list_long.do", {pageno:3}, function(data){
console.log("page3 success : " + (new Date()).toLocaleTimeString());
console.log(data);
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
그렇다면 어떻게 동기식으로 처리해야 할까?
아래와 같은 방법을 쓸 수 있다.
callback_jqXHR_then.html
: get이 끝나는 시점에 jqxhr객체를 통해서 호출이 끝나는 순간 then(function)을 실행 -> 리턴객체가 끝나는 시점에 다시 then으로 다시 함수 호출
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
// then은 $get() 함수가 호출된 jqXHR.then이고, 이것은 해당 요청이 완료된 후라는 뜻이다
// 순서대로 호출되는 것을 확인할 수 있다.
function reqList(){
$.get("/Contact/list_long.do", {pageno:1}).then(function(data){
console.log("promise page 1 : " + (new Date()).toLocaleTimeString());
console.log(data);
return $.get("/Contact/list_long.do", {pageno:2});
}).then(function(data){
console.log("promise page 2 : " + (new Date()).toLocaleTimeString());
console.log(data);
return $.get("/Contact/list_long.do", {pageno:3});
}).then(function(data){
console.log("promise page 3 : " + (new Date()).toLocaleTimeString());
console.log(data);
})
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
jqXHR_Multi.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
function reqList(){
//default가 3 이므로 0은 3개 / 1은 5개
var jqXHR0 = $.get("/Contact/list_long.do", {pageno:1});
var jqXHR1 = $.get("/Contact/list.do", {pageno:3, pagesize:5});
// 2개의 요청이 모두 완료되었을 때 호출
/* data0, data1 => type은 Array Object
data0[0], data[0] => type은 string
string을 js객체로 변환 => JSON.parse()
*/
$.when(jqXHR0, jqXHR1).done(function(data0, data1){
console.log(data0);
console.log(data1);
var obj0 = JSON.parse(data0[0]);
var obj1 = JSON.parse(data1[0]);
//contacts라는 필드에 접근해서 갯수를 얻어낸 것이다.
var totalCount = obj0.contacts.length +
obj1.contacts.length;
console.log("2번의 요청으로 조회된 데이터 건수의 합 : " + totalCount);
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
helper_function.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$("#save").click(function(){
var name = $("#name").val();
var gender = $("input.gender:checked").val();
var age = $("#age > option:selected").val();
var param = "name=" + encodeURIComponent(name);
param += "&gender=" + gender + "&age=" + age;
console.log(param);
});
});
</script>
</head>
<body>
<form id="f1">
이름 : <input type="text" id="name" name="name"/><br/>
성별 :
남 <input type="radio" class="gender" name="gender" value="M" checked/>
여 <input type="radio" class="gender" name="gender" value="F" /><br/>
연령대 :
<select id="age" name="age">
<option value="" selected>--연령대를 선택하세요</option>
<option value="10">~19</option>
<option value="10">20~29</option>
<option value="10">30~39</option>
<option value="10">40~49</option>
<option value="10">50~59</option>
<option value="10">60~</option>
</select>
</form>
<button id="save">저장</button>
</body>
</html>
helper 함수 이용시 form에 있는 데이터들을 쉽게 만들 수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
/*
helper 함수
1) $(form).serialize()
; 인코딩된 폼데이터로 생성(application/x-www-form-urlencoded 형식)
2) $(form).serializeArray()
; 객체 배열 생성
3) $.param()
; 객체/객체 배열을 인자로 받으면 인코딩된 폼데이터 생성
4) JSON.stringify(obj)
; js 객체 -> json 문자열
5) JSON.parse(str)
; json 문자열 -> js 객체
*/
$(document).ready(function(){
$("#save").click(function(){
// 1) application/x-www-form-urlencoded 형식으로 만드는 코드
// (form의 action)
// serialize시 일일이 뽑지 않아도 자동으로 만들어준다 (post에 보내는 형태로 만들어준다 )
// serialize array -> 배열로 만들어준다
var param = $("#f1").serialize();
console.log(param);
// 2) json 문자열로 만들고 싶다
var paramJson = $("#f1").serializeArray();
console.log(paramJson);
console.log(JSON.stringify(paramJson));
// 3) 객체/객체 배열 -> 인코딩 폼 데이터
console.log($.param(paramJson));
});
});
</script>
</head>
<body>
<form id="f1">
이름 : <input type="text" id="name" name="name"/><br/>
성별 :
남 <input type="radio" class="gender" name="gender" value="M" checked/>
여 <input type="radio" class="gender" name="gender" value="F" /><br/>
연령대 :
<select id="age" name="age">
<option value="" selected>--연령대를 선택하세요</option>
<option value="10">~19</option>
<option value="10">20~29</option>
<option value="10">30~39</option>
<option value="10">40~49</option>
<option value="10">50~59</option>
<option value="10">60~</option>
</select>
</form>
<button id="save">저장</button>
</body>
</html>
ajax_global_event.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
/* 어떤 ajax 통신이 진행되던
document에서 발생하는 모든 ajax의 이벤트를 감지하는 callback 함수 등록
전역 ajax 이벤트
*/
$(document).ready(function(){
$(document).ajaxStart(function(){
console.log("AJAX START !!");
}).ajaxStop(function(){
console.log("AJAX STOP !!");
}).ajaxSend(function(e, xhr, options){
console.log("AJAX SEND !!" + options.url);
}).ajaxSuccess(function(e, xhr, options, data){
console.log("AJAX SUCCESS !!" + options.url);
}).ajaxComplete(function(e, xhr, options){
console.log("AJAX COMPLETE !!" + options.url);
});
});
function reqList(){
$.get({
url : "/Contact/list.do",
beforeSend : function(){
console.log("1-beforeSend : list.do");
},
success : function(){
console.log("1-success : list.do");
},
complete : function(){
console.log("1-complete : list.do");
}
});
$.get({
url : "/Contact/list_long.do",
beforeSend : function(){
console.log("2-beforeSend : list_long.do");
},
success : function(){
console.log("2-success : list_long.do");
},
complete : function(){
console.log("2-complete : list_long.do");
}
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
전역이벤트 감지 후 로컬이벤트 감지 (시작과 보내는 것)
success, complete는 로컬이 먼저 감지되는 것을 확인 가능
전역이벤트
: 통신이 시작되고 일괄적으로 처리해줘야할 것이 있을 때 전역이벤트를 쓸 수 있다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$(document).ajaxStop(function(){
console.log("AJAX STOP !!");
});
// 모든 ajax에 timeout 1.9초가 적용이 된다
// 여기에 설정하는 것이 default설정으로 적용된다
$.ajaxSetup({
timeout : 1900,
// global : false, 전역이벤트 발생 x
error : function(jqXHR, status, error){
console.log("error : " + error);
}
});
});
function reqList(){
// 따로 timeout을 설정하지 않았으므로 위의 1.9초 적용
// 2초이므로 error
$.get("/Contact/list_long.do", function(data){
console.log(data);
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
global : false를 줬을 경우
ajaxPrefilter.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
// 비동기 전송이기 때문에 버튼을 여러번 누를 수 있다(요청 버튼)
// 그럼 get요청이 응답하고 리턴해버려서 reqList가 종료된다
// 그런데 여기서는 전송 중일때는 버튼을 눌러도 재요청이 발생하지 않도록 하기 위해 작성한 것이다.
// 즉 기존 전송이 완료되기 전에 재전송 막기
$(document).ready(function(){
// 현재 전송중인지를 체크하기 위해 만든 객체
var currentRequests = {}; //js 객체 생성
// ajax 통신 직전에 처리하는 일
$.ajaxPrefilter(function(options, originalOptions, jqXHR){
// abortOnRetry가 true면
if(options.abortOnRetry){
// url이 존재하냐 -> 처음엔 존재x (false) 빈 객체니까!
//한번 더 누르면 객체가 존재하므로 객체가 들어있으므로 true
if(currentRequests[options.url]){
jqXHR.abort();
console.log("abort Request");
}else {
// 빈 객체일 때 등록
currentRequests[options.url] = jqXHR;
}
}
});
// 기존 전송이 완료되기 전에 재전송 막기
$(document).ajaxComplete(function(e, jqxhr, options){
if(options.abortOnRetry){
delete currentRequests[options.url];
}
});
});
var count = 0;
function reqList(){
$.get({
url : "/Contact/list_long.do",
// 통신이 이루어지기 전에 항상 filter가 호출된다
abortOnRetry : true,
beforeSend : function(xhr, settings){
count++;
console.log("send " + count + " Request");
},
success : function(data){
console.log("success " + count + " Request !!");
console.log(data);
},
error : function(xhr, status, error){
console.log("error " + count + " Request");
}
});
}
function delList(){
$("#resp").html("");
}
</script>
</head>
<body>
<button type="button" onclick="reqList();">요청</button>
<button type="button" onclick="delList();">삭제</button>
<p id="resp"></p>
</body>
</html>
abort가 뜨는 것을 확인할 수 있다.