비동기식 자바 스크립트 + xml
XMLHttpRequest 객체 : 비동기식으로 웹프로그램을 요청하여 응답받아 처리하기 위한 객체 - AJAX Engine
AJAX 기능(Asynchronous Javascript + XML)을 이용하여 페이지의 요소(태그) 변경
ActiveX : 웹프로그램을 실행하기 위해 보조적으로 사용하는 것 (보안에 취약)
XMLHttpRequest 객체를 생성하여 저장 (전역변수와 함수 이용)
xhr=getXMLHttpRequest();XMLHttpRequest 객체의 준비상태(ReadyState)가 변경될 경우 호출될 이벤트 처리 함수 등록
xhr.onreadystatechange=changeHTML;//이벤트 처리 함수는 4번 호출XMLHttpRequest 객체로 open 메소드 호출 (준비상태 : 1)
xhr.open("get","hello_two.jsp",true);XMLHttpRequest 객체로 send 메소드 호출 (준비상태 : 2)
xhr.send(null);//웹프로그램 요청 - 준비상태가 자동으로 [3]과 [4]로 자동 변경 응답결과를 제공받아 페이지의 요소 조작 (DHTML)
document.getElementById("display").innerHTML=xhr.responseText;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<style type="text/css">
#display {
width: 50%;
padding: 5px;
margin: 10px;
font-size: 30px;
border: 1px solid red;
}
</style>
</head>
<body>
<h1>AJAX Programming</h1>
<hr>
<div id="display">Hello, AJAX!!!</div>
<div>
<button type="button" id="btn1">번역하기</button>
<button type="button" id="btn2">배경색 변경</button>
</div>
<script type="text/javascript">
/*
//Element 객체(button 태그)의 클릭 이벤트에 의해 호출될 이벤트 처리 함수 등록
document.getElementById("btn1").onclick=function() {
//DHTML(Dynamic HTML) 기능을 이용하여 페이지의 요소(태그) 변경
// => 현재 웹프로그램의 실행 결과를 이용하여 페이지의 요소 변경
document.getElementById("display").innerHTML="안녕하세요. 에이젝스!!!";
}
*/
//XMLHttpRequest 객체를 저장하기 위한 전역변수 선언
//XMLHttpRequest 객체 : 비동기식으로 웹프로그램을 요청하여 응답받아 처리하기 위한 객체 - AJAX Engine
var xhr=null;
//XMLHttpRequest 객체를 생성하여 반환하는 함수 선언
// => 브라우저 종류와 버전에 따라 XMLHttpRequest 객체를 생성하는 방법이 다양하므로 함수로 선언
function getXMLHttpRequest() {
if(window.ActiveXObject) {//IE4~IE6
try {
return new ActiveXObject("msxml2.XMLHTTP");//IE5~IE6
} catch (e) {
try {
return new ActiveXObject("MicrosoftXML.HTTP");//IE4
} catch (e) {
return null;
}
}
} else if(window.XMLHttpRequest) {//IE7 이상 또는 대다수의 웹브라우저
return new XMLHttpRequest();
} else {
return null;
}
}
//Element 객체(button 태그)의 클릭 이벤트에 의해 호출될 이벤트 처리 함수 등록
document.getElementById("btn1").onclick=function() {
//AJAX 기능(Asynchronous Javascript + XML)을 이용하여 페이지의 요소(태그) 변경
// => XMLHttpRequest 객체를 사용하여 비동기식으로 다른 웹프로그램을 요청하여 실행
//결과를 XML로 제공받아 페이지의 요소 변경
//1.XMLHttpRequest 객체를 생성하여 저장 - 전역변수와 함수 이용
xhr=getXMLHttpRequest();
//2.XMLHttpRequest 객체의 준비상태(ReadyState)가 변경될 경우 호출될 이벤트 처리 함수 등록
//XMLHttpRequest.readyState : XMLHttpRequest 객체의 준비상태 정보를 저장한 속성(Property)
// => XMLHttpRequest 객체의 준비상태는 순차적으로 자동 변경
// => 0(기본),1(요청 초기화 - open),2(요청 - send),3(응답대기 - 처리중),4(응답 - 결과)
//XMLHttpRequest.onreadystatechange : XMLHttpRequest 객체의 준비상태가 변경될 경우
//호출될 이벤트 처리 함수를 저장(등록)하기 위한 이벤트 속성(Property)
xhr.onreadystatechange=changeHTML;//이벤트 처리 함수는 4번 호출
//3.XMLHttpRequest 객체로 open 메소드 호출 - 준비상태 : 1
//XMLHttpRequest.open(method, url[, async]) : XMLHttpRequest 객체로 웹프로그램을
//요청하기 위한 정보를 설정하는 메소드
// => method : 요청방식 - GET, POST, PUT, PATCH, DELETE 등
// => url : 요청 웹프로그램의 URL 주소 - 현재 서버의 웹프로그램만 요청 가능
// => async : 동기식 통신 또는 비동기식 통신 구분 - false(동기식 통신) 또는 true(비동기식 통신 - 기본)
xhr.open("get","hello_two.jsp",true);//비동기식 통신 : 요청에 대한 응답의 기다림 미발생 - 다른 작업 가능
//xhr.open("get","hello_two.jsp",false);//동기식 통신 - 요청에 대한 응답의 기다림 발생 - 다른 작업 불가능
//4.XMLHttpRequest 객체로 send 메소드 호출 - 준비상태 : 2
//XMLHttpRequest.send(data) : XMLHttpRequest 객체로 웹프로그램을 요청하기 위한 메소드
// => data : 요청 웹프로그램에 전달할 값을 [이름=값&이름=값&...] 형식으로 표현하여 제공
// => 리퀘스트 메세지의 몸체부에 값을 저장하여 전달 - POST 방식으로 요청하여 값 전달
// => 전달값이 없거나 GET 방식으로 요청한 경우 매개변수에는 null 전달
xhr.send(null);//웹프로그램 요청 - 준비상태가 자동으로 [3]과 [4]로 자동 변경
}
//XMLHttpRequest 객체의 준비상태가 변경될 경우 호출될 이벤트 처리 함수
// => 요청에 대한 응답 결과를 제공받아 처리하는 함수
function changeHTML() {
/*
if(xhr.readyState==1) {
alert("요청 초기화 상태");
} else if(xhr.readyState==2) {
alert("요청 상태");
} else if(xhr.readyState==3) {
alert("응답 대기 상태");
} else if(xhr.readyState==4) {
alert("응답 완료 상태");
}
*/
//5.응답결과를 제공받아 페이지의 요소 조작 - DHTML
if(xhr.readyState==4) {
//XMLHttpRequest.status : 요청에 대한 실행 결과의 상태코드(StatusCode)를 저장한 속성(Property)
if(xhr.status==200) {//요청에 대한 정상적인 실행결과를 응답받은 경우
//XMLHttpRequest.responseText : 웹프로그램 요청에 대한 실행결과를 TEXT 또는 HTML로 저장한 속성(Property)
//XMLHttpRequest.responseXML : 웹프로그램 요청에 대한 실행결과를 XML로 저장한 속성(Property)
document.getElementById("display").innerHTML=xhr.responseText;
} else {//요청에 대한 비정상적인 실행결과를 응답받은 경우 - 에러코드 : 4XX or 5XX
alert("에러코드 = "+xhr.status);
}
} else {//요청에 응답결과를 제공받기 전인 경우
document.getElementById("display").innerHTML="<img src='images/loading.gif' width='50'>";
}
}
document.getElementById("btn2").onclick=function() {
document.getElementById("display").style="background-color: green";
}
</script>
</body>
</html>
GET 방식의 요청 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
POST 방식의 요청 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
xhr.open("post","data_two.jsp");//async 매개변수의 전달값이 생략된 경우 자동으로 true로 설정xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");xhr.send("name="+name);
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<style type="text/css">
#display {
width: 50%;
padding: 5px;
margin: 10px;
font-size: 30px;
border: 1px solid red;
}
</style>
</head>
<body>
<h1>AJAX - 값 전달</h1>
<hr>
<div id="display">요청 웹프로그램에 대한 실행 결과 출력</div>
<div>
이름 : <input type="text" id="name">
<button type="button" id="getBtn">GET 방식의 요청</button>
<button type="button" id="postBtn">POST 방식의 요청</button>
</div>
<script type="text/javascript">
var xhr=null;
function getXMLHtttpRequest() {
if(window.ActiveXObject) {
try {
return new ActiveXObject("msxml2.XMLHTTP");
} catch (e) {
try {
return new ActiveXObject("MicrosoftXML.HTTP");
} catch (e) {
return null;
}
}
} else if(window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return null;
}
}
//[GET 방식의 요청] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
document.getElementById("getBtn").onclick=function() {
//입력태그의 입력값을 반환받아 저장
var name=document.getElementById("name").value;
//입력값 검증
if(name=="") {
document.getElementById("display").innerHTML="이름을 입력해 주세요.";
return;
}
//입력태그 초기화
document.getElementById("name").value="";
xhr=getXMLHtttpRequest();
xhr.onreadystatechange=viewMessage;
//XMLHttpRequest 객체를 이용하여 웹프로그램을 GET 방식으로 요청
// => GET 방식으로 웹프로그램을 요청할 경우 질의문자열(QueryString)을 사용하여 값 전달
//문제점)전달값에 URL 주소로 표현 불가능한 문자값이 존재하는 경우 400 에러코드 발생
//해결법)전달값에 URL 주소로 표현 불가능한 문자값이 존재하는 경우 부호화 처리하여 전달
name=encodeURIComponent(name);
xhr.open("get","data_two.jsp?name="+name,true);
xhr.send(null);
}
//[POST 방식의 요청] 태그를 클릭한 경우 호출되는 이벤트 처리 함수 등록
document.getElementById("postBtn").onclick=function() {
//입력태그의 입력값을 반환받아 저장
var name=document.getElementById("name").value;
//입력값 검증
if(name=="") {
document.getElementById("display").innerHTML="이름을 입력해 주세요.";
return;
}
//입력태그 초기화
document.getElementById("name").value="";
xhr=getXMLHtttpRequest();
xhr.onreadystatechange=viewMessage;
//XMLHttpRequest 객체를 이용하여 웹프로그램을 POST 방식으로 요청
// => POST 방식으로 웹프로그램을 요청한 경우 send 메소드의 매개변수를 사용하여 값 전달
//문제점)send 메소드를 이용하여 값을 전달할 경우 "multipart/form-data" 형식(원시데이타)으로 값 전달
// => 요청 웹프로그램의 request 객체의 getParameter() 메소드로 전달값 반환 불가능
//해결법)"application/x-www-form-urlencoded" 형식(텍스트 데이타)으로 값이 전달되도록
//리퀘스트 메세지의 헤더 정보 변경
xhr.open("post","data_two.jsp");//async 매개변수의 전달값이 생략된 경우 자동으로 true로 설정
//XMLHttpRequest.setRequestHeader(header, value) : XMLHttpRequest 객체를 이용하여
//웹프로그램을 요청할 때 사용하는 리퀘스트 메세지의 헤더 정보를 변경하는 메소드
// => 리퀘스트 메세지의 몸체부에 저장된 값이 텍스트 형식의 문자값을 표현되도록 설정
// => open 메소드 호출 후 사용 가능
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("name="+name);
}
//요청 웹프로그램의 응답결과를 제공받아 페이지의 요소를 변경하는 이벤트 처리 함수
function viewMessage() {
if(xhr.readyState==4) {
if(xhr.status==200) {
document.getElementById("display").innerHTML=xhr.responseText;
} else {
alert("에러코드 = "+xhr.status);
}
}
}
</script>
</body>
</html>
POST 방식으로 요청하여 전달된 값에 대한 캐릭터셋 변경
전달값을 반환받아 저장
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//POST 방식으로 요청하여 전달된 값에 대한 캐릭터셋 변경
request.setCharacterEncoding("utf-8");
//전달값을 반환받아 저장
String name=request.getParameter("name");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
</head>
<body>
<%=name %>님, 환영합니다.
</body>
</html>
/* AJAX Module : 전역변수와 함수를 이용하여 AJAX 기능 제공 */
var xhr=null;
function getXMLHttpRequest() {
if(window.ActiveXObject) {//IE4 ~ IE6
try {
return new ActiveXObject("msxml2.XMLHTTP");//IE5 ~ IE6
} catch (e) {
try {
return new ActiveXObject("MicrosoftXMLHTTP");//IE4
} catch (e) {
return null;
}
}
} else if(window.XMLHttpRequest) {//IE7 이상 또는 기타 브라우저
return new XMLHttpRequest();
} else {
return null;
}
}
/* 요청과 응답 처리를 위한 함수 선언 */
function sendRequest(method, url, param, callback) {
xhr=getXMLHttpRequest();
//요청방식에 대한 검증과 저장
var httpMethod=method?method:"get";
if(httpMethod!="get" && httpMethod!="post") {
httpMethod="get";
}
//전달값에 대한 검증과 저장
var httpParam=(param==null || param=="")?null:param;
//요청 URL 주소 저장
var httpUrl=url;
//GET 방식으로 요청시 전달값이 존재할 경우 URL 주소에 QueryString 추가
if(httpMethod=="get" && httpParam!=null) {
httpUrl=httpUrl+"?"+httpParam;
}
//응답결과를 제공받아 처리하기 위한 함수 등록
xhr.onreadystatechange=callback;
//웹어플리케이션 요청
xhr.open(httpMethod, httpUrl);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(httpMethod=="post"?httpParam:null);
}
AJAX 기능 제공
<script type="text/javascript" src="js/xhr.js"></script>AJAX 기능을 제공하는 모듈을 사용하여 요청과 응답 처리 - sendRequest 함수 호출
sendRequest("get", "module_two.jsp", "id="+id+"&name="+name, viewMessage);sendRequest("post", "module_two.jsp", "id="+id+"&name="+name, viewMessage);
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script type="text/javascript" src="js/xhr.js"></script>
<style type="text/css">
#display {
width: 50%;
padding: 5px;
margin: 10px;
font-size: 30px;
border: 1px solid red;
}
</style>
</head>
<body>
<h1>AJAX Module</h1>
<hr>
<div id="display">요청 웹프로그램에 대한 실행 결과 출력</div>
<table>
<tr>
<td>아이디</td>
<td><input type="text" id="id"></td>
</tr>
<tr>
<td>이름</td>
<td><input type="text" id="name"></td>
</tr>
<tr>
<td colspan="2"><button type="button" id="btn">요청(AJAX)</button></td>
</tr>
</table>
<script type="text/javascript">
document.getElementById("btn").onclick=function() {
var id=document.getElementById("id").value;
if(id=="") {
document.getElementById("display").innerHTML="아이디를 입력해 주세요.";
return;
}
var name=document.getElementById("name").value;
if(name=="") {
document.getElementById("display").innerHTML="이름을 입력해 주세요.";
return;
}
document.getElementById("id").value="";
document.getElementById("name").value="";
//AJAX 기능을 제공하는 모듈을 사용하여 요청과 응답 처리 - sendRequest 함수 호출
/*
//GET 방식으로 웹프로그램을 요청한 경우 모든 전달값을 부호화 처리하여 전달
id=encodeURIComponent(id);
name=encodeURIComponent(name);
sendRequest("get", "module_two.jsp", "id="+id+"&name="+name, viewMessage);
*/
sendRequest("post", "module_two.jsp", "id="+id+"&name="+name, viewMessage);
}
function viewMessage() {
if(xhr.readyState==4) {
if(xhr.status==200) {
document.getElementById("display").innerHTML=xhr.responseText;
} else {
alert("에러코드 = "+xhr.status);
}
}
}
</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("utf-8");
String id=request.getParameter("id");
String name=request.getParameter("name");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
</head>
<body>
<%=name %>[<%=id %>]님, 환영합니다.
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX</title>
<script type="text/javascript" src="js/xhr.js"></script>
<style type="text/css">
div {
font-size: 20px;
margin: 10px;
}
</style>
</head>
<body>
<h1>브라우저 캐싱</h1>
<hr>
<div>
클라이언트 시스템의 현재 날짜와 시간은
<span id="clientTime">2023년 1월 9일 16시 16분 22초</span>입니다.
</div>
<div>
서버 시스템의 현재 날짜와 시간은
<span id="serverTime">2023년 1월 9일 16시 16분 22초</span>입니다.
</div>
<script type="text/javascript">
//브라우저가 실행되는 시스템(클라이언트)의 현재 날짜와 시간을 제공받아 태그를 변경하는 함수
// => 클라이언트에 따라 다른 결과 제공 가능
function displayClientTime() {
var now=new Date();
var displayTime=now.getFullYear()+"년 "+(now.getMonth()+1)+"월 "+now.getDate()+"일 "
+now.getHours()+"시 "+now.getMinutes()+"분 "+now.getSeconds()+"초";
document.getElementById("clientTime").innerHTML=displayTime;
}
displayClientTime();
setInterval(displayClientTime, 1000);
//웹프로그램을 실행하는 시스템(서버)의 현재 날짜와 시간을 제공받아 태그를 변경하는 함수
// => 서버의 날짜와 시간을 제공받아 사용하므로 모든 클라이언트에게 동일한 결과 제공
//문제점)동일한 웹프로그램을 지속적으로 요청한 경우 브라우저 캐싱 기능에 의해 서버에서
//제공하는 응답결과가 아닌 기존 응답결과를 재사용 - 최초 응답결과를 계속 사용하여 응답 처리
//해결법-1)웹프로그램에 대한 요청 URL 주소를 지속적으로 변경하여 요청 - 질의문자열(QueryString) 이용
//해결법-2)요청 웹프로그램에서 응답결과에 대한 브라우저 캐싱 기능을 무효화 처리
function displayServerTime() {
//sendRequest("get", "clock_two.jsp?dummy="+new Date().getTime(), null, function() {
sendRequest("get", "clock_two.jsp", null, function() {
if(xhr.readyState==4) {
if(xhr.status==200) {
document.getElementById("serverTime").innerHTML=xhr.responseText;
} else {
alert("에러코드 = "+xhr.status);
}
}
});
}
displayServerTime();
setInterval(displayServerTime, 1000);
</script>
</body>
</html>
String protocol=request.getProtocol();
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//request.getProtocol() : 요청 웹프로그램에서 사용하는 통신규약(Protocol)을 반환하는 메소드
String protocol=request.getProtocol();
//요청에 대한 응답결과를 브라우저 캐싱 기능에 의해 사용되지 않도록 설정
//1. jsp문서일 경우 (if문) 2. html문서일 경우 (meta태그 이용)
if(protocol.equals("HTTP/1.0")) {
response.setDateHeader("Expires", -1);//캐싱 만료기간 설정
response.setHeader("Pragma", "no-cache");//캐싱 기능 비활성화 설정
} else if(protocol.equals("HTTP/1.1")) {
response.setHeader("Cache-control", "no-cache");//캐싱 기능 비활성화 설정
}
Date now=new Date();
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초");
String displayTime=simpleDateFormat.format(now);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<title>AJAX</title>
</head>
<body>
<%=displayTime %>
</body>
</html>