평범한 연구소

[jQuery] ajax 본문

Pront/jQuery

[jQuery] ajax

soyeonisgood 2022. 10. 22. 16:52

Ajax ( Asynchronous Javascript and XML)

  • 비동기 자바스크립트 XML. XML에 기반한 종합 기술로 에이싱크러너스 자바스크립트 XML의 줄인말.
  • HTML, CSS, JS, DOM, XML 등 기존에 사용되던 여러 기술을 함께 사용하는 개발 기법이다.
  • 빠르게 동작하는 동적인 웹페이지를 만들기 위한 개발 기법 중 하나.
  • 웹페이지 전체를 다시 로딩하지 않고도, 웹의 일부만 갱신할 수 있다. 즉, 백드라운드 영역에서 서버와 통신하여 그 결과를 웹페이지 일부에 표시 가능하다.
  • 서버와 다양한 형태의 데이터를 주고 받을 수 있다.
    • JSON 
    • XML
    • HTML
    • 텍스트파일 등

 

Ajax의 장점과 한계

  • 웹페이지 전체를 다시 로딩하지 않고도 일부만 갱신 가능.
  • 웹페이지가 로드된 후에 서버로 데이터 요청을 보내고 받을 수 있다.
  • 백드라운드 영역에서 서버로 데이터를 보낸다. 비동기 통신으로 데이터를 보내고 나서도 사용자는 다른 작업을 할 수 있다.
  • 데이터만 들어가 있는 형식으로 응답을 받으므로 서버 측 처리속도가 빠르고 전송 데이터양도 적다.
  • 클라이언트가 서버에 데이터를 요청하는 클라이언트 폴링 방식. 서버 푸시 방식의 실시간 서비스는 만들 수 없다.
    • 클라이언트 폴링 (client polling): 사용자가 직접 원하는 정보를 서버에게 요청하여 얻는 방식
    • 서버 푸시 (server push): 사용자가 요청하지 않아도 서버가 자동으로 특정 정보를 제공. (ex. 스마트폰 푸시알림)
  • 바이너리 데이터를 주고받을 수 없다.
  • 스크립트가 포함된 서버가 아닌, 다른 서버로는 ajax 요청 보낼 수 없다.
  • 클라이언트의 PC로 ajax 요청 보낼 수 없다.

 

Ajax 동작 원리

  • 유저가 이벤트를 발생시켜 자바스크립트(JS) 실행.
  • JS는 XMLHttpRequest 객체를 사용하여 서버로 요청. (웹브라우저는 요청을 보내고 서버의 응답 기다릴 필요 없이 다른 작업 처리 가능.)
  • 서버는 전달받은 ajax 요청 처리.
  • 서버는 처리한 결과를 JSON, XML, HTML 형태의 데이터로 웹브라우저에 전달. (전체 페이지 내용X 필요한 데이터만.)
  • 서버로부터 전달받은 데이터로 웹페이지 일부분만 갱신.

 

XMLHttpRequest 객체

  • 웹브라우저가 서버와 데이터를 교환할 때 사용한다.
  • ajax의 가장 핵심적인 구성 요소
open(method, url, async, user, password) 새로 만든 요청을 초기화하거나 기존 요청 다시 초기화.
서버로 보낼 ajax 요청의 형식 설정.
method: GET,POST, 등 과 같이 사용할 HTTP 요청 방법 (필수)
url: request를 송신하는 URL (필수)
async: 비동기적으로 작업을 수행할지 여부 (default: true, 비동기)
user: 인증 목적으로 사용할 이름 (default: null)
password: 인증 목적으로 사용할 패스워드 (default: null)
send(body) 요청을 서버로 보낸다. 요청이 비동기인 경우 메소드는 요청이 보내지고 이벤트를 사용하여 결과가 전달되는 즉시 리턴.
setRequestHeader(header, value) header에 해당하는 value 값으로 HttpRequest 헤더에 값을 설정하는 메소드. 반드시 opne() 메소드 다음에 위치해야함.
onreadystatechange readyState 속성이 변경 될 때마다 호출되는 EventHandler
readyState XMLHttpRequest 클라이언트가 있는 다음 중 하나의 상태 반환.
0(UNSENT): XMLHttpRequest 객체 생성됨. open() 메소드 호출 전
1(OPENED): open() 메소드 호출됨.
2(HEADERS_RECEIVED): send()가 호출되었고 헤더,상태 사용 가능.
3(LOADING): interactive. 응답 받고 있는 중간 상태.
4(DONE): completed. 모든 요청 응답 완료.
responseText 요청이 전송된 후 서버에서 받은 텍스트 반환 (읽기 전용)
responseXML 요청에 의해 검색된 HTML 또는 XML을 포함하는 Document를 반환(읽기 전용).
status XMLHttpRequest의 응답에 대한 숫자 HTTP 상태 코드를 반환(읽기 전용). 
0: 요청 완료 전.
200: OK. 성공.
404: Not Found. 서버가 요청 페이지 찾을 수 없음.

 

 


ajax 활용 예제

 

GET

// AJAX 객체 생성
function createXMLHttpRequest() {
	let req = null;
	
	try {
		req = new XMLHttpRequest();
	} catch (e) {
	}
	
	return req;
}

var httpReq = null;

function sendOk() {
	let n1 = document.querySelector("#num1").value;
	let o = document.querySelector("#oper").value;
	let n2 = document.querySelector("#num2").value;
	
	let query = "num1="+n1+"&num2="+n2+"&oper="+encodeURIComponent(o);
	let url = "ex02_ok.jsp?"+query; // get 방식 주소

	// AJAX 객체 생성
	httpReq = createXMLHttpRequest();
	
	// 서버에서 처리하고 결과를 전송할 자바스크립트 함수 지정
	httpReq.onreadystatechange = callback;
	
	// open - AJAX 요청의 형식을 설정
	httpReq.open("GET", url, true);
	
	// send
	httpReq.send(null);
	
}

function callback() {
	if(httpReq.readyState === 4) {  // 요청상태 - 4:모든응답요청완료
		if(httpReq.status === 200) { // 서버로부터 전달받은 상태코드 - 200:성공(OK)
			printData();
		}
	}
}

function printData() {
	let result = httpReq.responseText;
	
	document.querySelector("#resultLayout").innerHTML = result;
}

// ex02_ok.jsp, ex03_ex.jsp
<%
	request.setCharacterEncoding("utf-8");

	int num1 = Integer.parseInt(request.getParameter("num1"));
	String oper = request.getParameter("oper");
	int num2 = Integer.parseInt(request.getParameter("num2"));
	
	int result = 0;
	switch(oper){
	case "+" : result = num1 + num2; break;
	case "-" : result = num1 - num2; break;
	case "*" : result = num1 * num2; break;
	case "/" : result = num1 / num2; break;
	}
%>

<p style="color: blue;">
	<%=num1%> <%=oper%> <%=num2%> = <%=result%>
</p>

 

POST

  • post 방식은 아래 코드 필수.
    • httpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); .
  • get방식은 파라미터를 주소줄에 넘기고 post방식은 send로 넘긴다. 
    • httpReq.send(query);
function sendOk() {
  	...
	// open - AJAX 요청의 형식을 설정
	httpReq.open("POST", url, true);
	
	// post 방식에서는 필수
	httpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	
	// send
	httpReq.send(query); // POST방식일 때 파라미터를 send로 넘김. GET은 주소줄에.	
}

 

XML

function printData() {
	let xmlDoc = httpReq.responseXML;
	console.log(xmlDoc);
	
	let root = xmlDoc.getElementsByTagName("guest")[0];
	let dataCount = xmlDoc.getElementsByTagName("dataCount")[0].firstChild.nodeValue;
	
	let out = "<p>전체데이터개수 : " + dataCount + "</p>";
	
	let records = root.getElementsByTagName("record");
	for(let item of records) {
		let num = item.getAttribute("num");
		let name = item.getElementsByTagName("name")[0].firstChild.nodeValue;
		let content = item.getElementsByTagName("content")[0].firstChild.nodeValue;
		
		out += "<p>번호:"+num+"<br>";
		out += "이름:"+name+"<br>";
		out += "내용:"+content+"<p><hr>";
	}
    
	document.querySelector("#resultLayout").innerHTML = out;
}

// ex04_ok.jsp

<%@ page contentType="text/xml; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<% 
	request.setCharacterEncoding("utf-8");

	String name = request.getParameter("name"); 
	String content = request.getParameter("content"); 		
	
%>

<guest>
	<dataCount>5</dataCount>
	<%for(int i=1; i<=5; i++) { %>
		<record num="<%=i%>">
			<name><%= (char)(i+64) + " - " + name %></name>
			<content><![CDATA[<%= (char)(i+64) + " - " + content %>]]></content>
		</record>
	<% } %>
</guest>

 

JSON

  • 문자열을 JSON 객체로 변환.
    • JSON.parse(변환할문자열);
function printData() {
	let result = httpReq.responseText;
	// console.log(result);
	
	// 문자열을 자바스크립트 JSON 객체로 변환
	let job = JSON.parse(result);
	
	let out = "";
	
	out = "<p>개수 : " + job.count + "</p>";
	for(let item of job.list) {
		let num = item.num;
		let name = item.name;
		let content = item.content;
		
		out += "<p>번호:"+num+"<br>";
		out += "이름:"+name+"<br>";
		out += "내용:"+content+"<p><hr>";
	}
	
	document.querySelector("#resultLayout").innerHTML = out;
}

// ex05_ok.jsp

<%@page import="org.json.JSONArray"%>
<%@page import="org.json.JSONObject"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");

	String name = request.getParameter("name");
	String content = request.getParameter("content");
	
	// JSON 형식 1 : {"이름1":"값1", "이름2":"값2"}
	// JSON 형식 2 : {"이름":[{"이름1":"값1", "이름2":"값2"}]}
	
	/*
	StringBuilder sb = new StringBuilder();
	
	sb.append("{");
	sb.append("\"name\":\""+name+"\"");
	sb.append(", \"content\":\""+content+"\"");
	sb.append("}");
	out.print(sb.toString());
	*/
	
	JSONObject job = new JSONObject();
	job.put("count", 5);
	
	JSONArray jarr = new JSONArray();
	for(int i=1; i<=5; i++) {
		JSONObject ob = new JSONObject();
		ob.put("num", i);
		ob.put("name", (char)(i+64)+"-"+name);
		ob.put("content", (char)(i+64)+"-"+content);
		
		jarr.put(ob);
	}
	job.put("list", jarr);
	
	out.print(job.toString());
%>

 

ajax, jquery 예제

  • post 방식
  • 간단한 계산기 
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>

<script type="text/javascript">
$(function() {
	$(".btnSend").click(function() {
		let query = $("form[name=calcForm]").serialize();
		let url = "ex05_ok.jsp";
	
		$.ajax({
			type:"post",
			url:url,
			data:query, 
			success:function(data) {
				$("#resultLayout").html(data);
			},
			beforeSend:check, // 서버 전송 전 헤더 등을 추가하거나 유효성 검사
			error: function(e) {
				console.log(e.responseText);
			}
		});
		
	});
	
	function check() {
		// 유효성 검사 
		let num1 = $("#num1").val();
		if( ! /^(\d+)$/.test(num1)){
			 $("#num1").focus();
			 return false;
		}
		
		let num2 = $("#num2").val();
		if( ! /^(\d+)$/.test(num1)){
			 $("#num2").focus();
			 return false;
		}
		
		return true;
	}
	
});


</script>

</head>
<body>

<h3>jquery AJAX : GET - $.ajax()</h3>
<p id="msg"></p>

<form name="calcForm" action="ex01_ok.jsp" method="post">
	<input type="text" name="num1" id="num1">
	<select name="oper" id="oper">
		<option value="+">더하기</option>
		<option value="-">빼기</option>
		<option value="*">곱하기</option>
		<option value="/">나누기</option>
	</select>
	<input type="text" name="num2" id="num2">
	<button type="button" class="btnSend"> = </button>
</form>
<hr>

<div id="resultLayout"></div>

</body>
</html>

// ex05_ok.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");

	int num1 = Integer.parseInt(request.getParameter("num1"));
	String oper = request.getParameter("oper");
	int num2 = Integer.parseInt(request.getParameter("num2"));
	
	int result = 0;
	switch(oper){
	case "+" : result = num1 + num2; break;
	case "-" : result = num1 - num2; break;
	case "*" : result = num1 * num2; break;
	case "/" : result = num1 / num2; break;
	}
%>


<p>
	<%=num1%> <%=oper%> <%=num2%> = <%=result%>
</p>

 

  • json 방식
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>

<script type="text/javascript">
$(function() {
	$(".btnSend").click(function() {
		let query = $("form[name=myForm]").serialize();
		let url = "ex08_ok.jsp";
		
		$.ajax({
			type:"post",
			url:url,
			data:query,
			dataType:"json",
			success:function(data){
				let out = "<p>개수:"+data.count+"</p>";
				
				$(data.list).each(function(index, item) {
					let num = item.num;
					let name = item.name;
					let content=item.content;

					out += "<p>번호:"+num+"<br>";
					out += "이름:"+name+"<br>";
					out += "내용:"+content+"</p><hr>";
					
				});
				
				$("#resultLayout").html(out);
				
			},
			error:function(e){
				console.log(e.responseText);
			}
		});
	});
	

});
</script>

</head>
<body>

<h3>jquery AJAX : $.ajax() - JSON</h3>

<form name="myForm">
	<p> 이름 : <input type="text" name="name" id="name"> </p>
	<p> 내용 : <textarea rows="3" cols="60" name="content" id="content"></textarea>
	<p>
		<button type="button" class="btnSend">등록</button>
	</p>
</form>
<hr>

<div id="resultLayout"></div>

</body>
</html>

// ex08_ok.jsp

<%@page import="org.json.JSONArray"%>
<%@page import="org.json.JSONObject"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%
	request.setCharacterEncoding("utf-8");

	String name = request.getParameter("name");
	String content = request.getParameter("content");
	
	// JSON 형식 1 : {"이름1":"값1", "이름2":"값2"}
	// JSON 형식 2 : {"이름":[{"이름1":"값1", "이름2":"값2"}]}
	
	/*
	StringBuilder sb = new StringBuilder();
	
	sb.append("{");
	sb.append("\"name\":\""+name+"\"");
	sb.append(", \"content\":\""+content+"\"");
	sb.append("}");
	out.print(sb.toString());
	*/
	
	JSONObject job = new JSONObject();
	job.put("count", 5);
	
	JSONArray jarr = new JSONArray();
	for(int i=1; i<=5; i++) {
		JSONObject ob = new JSONObject();
		ob.put("num", i);
		ob.put("name", (char)(i+64)+"-"+name);
		ob.put("content", (char)(i+64)+"-"+content);
		
		jarr.put(ob);
	}
	job.put("list", jarr);
	
	out.print(job.toString());
%>

 

ajax 동작과 관련된 jQuery 예제

$(function() {
	$(document)
		.ajaxStart(function() {
			$("#loading").center();
			
			$("#loadingLayout").fadeTo("slow", 0.5);
		})
		.ajaxComplete(function() {
			$("#loadingLayout").hide();
		});
});