프론트
Ajax
짱코딩러
2022. 10. 4. 18:06
!사용전에 lib폴더에 XML파서(xalan.jar, xercesImpl.jar, xml-apis.jar 등)를 넣어줌!
Ajax
웹 페이지 전체를 다시 로딩(동기 통신)하지 않고도, 웹페이지의 일부분만 갱신할 수 있게 해주는 개발 기법(비동기)
이때 서버에서 주고받는 데이터의 형태는 JSON, XML, HTML 등이 있다.
(클라이언트를 통해 요청을 받아 실행하는 형식으로만 처리됨.)
처리 과정
1.이벤트(load, click) 발생으로 이벤트 핸들러 역할의 JavaScript 함수를 호출합니다.
2.핸들러 함수에서 XMLHttpRequest 객체를 생성합니다.
요청이 종료되었을 때 처리할 기능을 콜백 함수로 만들어 등록합니다.
3.XMLHttpRequest 객체를 통해 서버에 HTTP 요청을 보냅니다.
4.요청을 받은 서버는 요청 결과를 XML이나 JSON 등의 데이터로 구성하여 브라우저로 응답합니다.
5.XMLHttpRequest 객체에 의해 등록된 콜백 함수를 호출하여 응답 결과를 페이지에 반영합니다.
*전달받은 데이터가 XML이면 => XMLHttpRequest객체의 responseXML사용
JSON이면 => XMLHttpRequest객체의 responseText사용
var request = new XHLHttpRequest();//웹사이트에 요청을 보내는 객체
function searchFunction(){ //서버의 응답에 따른 로직 작성
//encodeURLComponent() 안에 있는 값을 utf-8으로 인코딩해줌
//인코딩 된 값이 Post방식으로 파라미터로 넘어가게 되는것임!
//그럼 서블릿에서는 처리해서 JSON으로 출력해줌
request.open("Post","./UserSearchServlet?userName="
+encodeURIComponent(document.getElementById("userName").value),true);
//서버가 준비되면 시행될 함수를 지정(searchProcess) *부르는게 아니라 지정만 하는거임
request.onreadystatechange = searchProcess;
request.send(null);
}
function searchProcess(){
var table = document.getElementById("ajaxTable");
table.innerHTML="";//공간을 비워줌
//서버에서 정상적으로 응답을 받았고 && ajax요청이 정상적으로 처리 되었으면
if(request.readyState == 4 && request.status==200){
//넘어온 JSON을 담아줌(텍스트 문자열로 반환)
var object = eval('('+request.responseText+')');
//담은 JSON을
var result = object.result;
}
}
//open(요구방식,요구하려는 url,비동기식 유무) *false시 동기식
request.open('GET', 'http://www.example.org/some.file'[, true]);
//post방식으로 보낼 경우
request.send(null);
JSON(responseText)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
//window객체에서 로드이벤트 발생 시 호출되는 핸들러함수 등록
window.onload = function() {
//웹사이트에 요청을 보내는 객체(request)
var xhr = new XMLHttpRequest();
//서버가 실행되면
xhr.onreadystatechange = function() {
//응답했을때
if (xhr.readyState == XMLHttpRequest.DONE) {
//성공적이면
if (xhr.status == 200) {
//응답받은 텍스트
var str = xhr.responseText;
//를 JavaScript 객체로 변환
var result = JSON.parse(str);
var output = "";
//텍스트를 반복추출
for (var i in result)
output += "<h3>"
+ result[i]
+ "</h3>";
document.body.innerHTML += output;
}
}
};
xhr.open('GET', 'content/sample.json', true);
xhr.send();
};
</script>
</head>
<body>
<h2>onreadystatechange 속성 사용 - JSON응답</h2>
<hr>
</body>
</html>
content/sample.json
{ "name" : "자바스크립트",
"age" : 21,
"kind" : "웹앱개발 전용 OPP언어"}
XML(responseXML)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
//window객체에서 로드이벤트 발생 시 호출되는 핸들러함수 등록
window.onload = function() {
//웹사이트에 요청을 보내는 객체(request)
var xhr = new XMLHttpRequest();
xhr.onload = function() {
//서버의 응답이 성공인지 체크
if (xhr.status == 200) {
//응답한 XML문서에 대한 DOM객체들의 최상위 객체인 Document객체 추출
var xml = xhr.responseXML;
//응답한 XML의 루트엘리먼트<testxml>태그에 대한 DOM객체를 가져옴
var rootE = xml.getElementsByTagName('testxml');
var output = '';
//<testxml>의 자식 엘리먼트들을 반복추출
//엔터친것 까지 자식으로 포함되기 때문에 i += 2 이렇게 불러와줌.
for (var i = 1; i < rootE[0].childNodes.length; i += 2)
output += "<h3>"
+ rootE[0].childNodes[i].firstChild.nodeValue
+ "</h3>";
document.body.innerHTML += output;
}
};
//가져와(GET)
xhr.open('GET', 'content/sample.xml', true);
xhr.send();
};
</script>
</head>
<body>
<h2>onreadystatechange 속성 사용 - XML응답</h2>
<hr>
</body>
</html>
content/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<testxml>
<name>자바스크립트</name>
<age>21</age>
<kind>웹앱개발 전용 OPP 언어</kind>
</testxml>
로그인
<html>
<head>
<meta charset="UTF-8">
<title>Ajax테스트</title>
<script>
//핸들러 함수
window.addEventListener("load", function() {
//#loginb가 클릭되면 핸들버튼프로세스 실행
document.getElementById("loginb").onclick = handleButtonPress;
});
var xhr;
var id;
function handleButtonPress(e){
//클릭한 개체의 원래 동작을 막아주는 메서드(디폴트 이벤트 핸들러 해제.새고안되도록 함.)
e.preventDefault();
xhr = new XMLHttpRequest();
form = document.querySelector("#loginf");
id = document.querySelector("#id");
var passwd = document.querySelector("#passwd");
//submit이 아니라 Ajax형태로 전달하기 위해서 queryString으로 만듦
//encodeURIComponent()==괄호 속 값을 암호화
var queryString = "id="+encodeURIComponent(id.value)+"&passwd="+passwd.value;
//이벤트 등록(이벤트명, 실행할 함수명)
xhr.addEventListener("load", handleResponse);
xhr.open("POST", form.action, true);
//form태그의 action 속성에 대한 비동기post방식 요청을 XMLHttpRequest객체에 설정
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//POST방식으로 Ajax통신을 요청할 때는 요청 body에 담겨서 전달되는 내용에 대한 타입 정보를 설정
xhr.send(queryString);//QueryString을 body영역에 담아서 서버에 Ajax요청 전송
}
//콜백함수
function handleResponse() {
//JSON 문자열을 JavaScript 객체로 변환
var jsonObj = JSON.parse(xhr.responseText);
var output = document.querySelector("output");
if (jsonObj.result == "ok") {
output.textContent="로그인 성공!!";
output.style.color = "blue";
} else if (jsonObj.result == "fail") {
output.textContent="로그인 실패!!";
output.style.color = "red";
form.reset();
id.focus();
}
}
</script>
</head>
<body>
<h3>계정과 패스워드를 입력해 주세요.</h3>
<form id="loginf" action="content/login.jsp">
<table>
<tr>
<td><label for="id">계정</label></td>
<td><input type="text" id="id" name="id" required/></td>
</tr>
<tr>
<td><label for="passwd">패스워드</label></td>
<td><input type="password" id="passwd" name="passwd" required/></td>
</tr>
<tr>
<td><input type="submit" id="loginb" value="로그인" /></td>
<td><output></output></td>
</tr>
</table>
</form>
</body>
</html>
content/login.jsp
<%@ page language="java" contentType="application/json; charset=UTF-8"%>
<%
if(request.getParameter("id").equals("1234") &&
request.getParameter("passwd").equals("1234")) {
%>
{ "result" : "ok" }
<%
}else{
%>
{ "result" : "fail" }
<%
}
%>
날씨정보
<html>
<head>
<meta charset="UTF-8">
<title>Ajax테스트</title>
<style>
table{
border-collapse:collapse;
width: 100%;
border: 1px solid black;
}
td{
border: 1px solid black;
padding-left: 5px;
}
</style>
</head>
<body>
<script>
window.onload = function(){
var xhr = new XMLHttpRequest();
xhr.onload = function(event){
if(xhr.status == 200){
var str = xhr.responseText;
//2.#output에다가 뿌려
var target = document.getElementById('output');
target.innerHTML = str;
}
};
//1.아래 과정이 200이면
xhr.open('GET','content/rss.jsp', true);
xhr.send();
};
</script>
</body>
<h2 style="text-align: cecnter">실시간 날씨 정보입니다.</h2>
<div id="output" style="width:350px; margin:10px auto"></div>
</html>
content/rss.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/xml" prefix="x"%>
<c:catch var="err">
<c:import var="weather"
url="http://www.kma.go.kr/wid/queryDFSRSS.jsp?zone=1168064000">
</c:import>
<!-- xml 파싱하기 -->
<x:parse varDom="wrss" xml="${weather}"></x:parse>
<x:out select="$wrss/rss/channel/title"></x:out><br/>
<table>
<tr>
<th colspan="2">현재날씨</th>
</tr>
<tr>
<td>기준시간</td>
<td>
<x:out select="$wrss/rss/channel/pubDate"/>
</td>
</tr>
<tr>
<td>기온</td>
<td>
<x:out select="$wrss/rss/channel/item/description/body/data/temp"/>
</td>
</tr>
<tr>
<td>습도</td>
<td>
<x:out select="$wrss/rss/channel/item/description/body/data/reh"/>%
</td>
</tr>
<tr>
<td>강수확률</td>
<td>
<x:out select="$wrss/rss/channel/item/description/body/data/pop"/>%
</td>
</tr>
</table>
</c:catch>
<c:if test="${err!=null}">
${err}
</c:if>
※readyState※
- 0 (uninitialized) - (request가 초기화되지 않음)
- 1 (loading) - (서버와의 연결이 성사됨)
- 2 (loaded) - (서버가 request를 받음)
- 3 (interactive) - (request(요청)을 처리하는 중)
- 4 (complete) - (request에 대한 처리가 끝났으며 응답할 준비가 완료됨)