통신 XMLHttpRequest 제대로 활용하기

황제낙엽 2017.08.01 15:33 조회 수 : 58

sitelink1 http://egloos.zum.com/codecrue/v/2217566 
sitelink2  
sitelink3  
sitelink4  
extra_vars4  
extra_vars5  
extra_vars6  
 
JavaScript에서 서버로 데이터를 요청하고 수신하는 방법중에 흔히 사용하는 방법이 XMLHttpRequest 이다.
이는 client side인 웹 브라우저에서 server side 인 WAS 서버에 데이터를 요청하고 이를 수신하도록 편리하게 제공되는 객체이다.
이에 대해 적절한 샘플코드와 이해를 통하여 JavaScript를 입문하고자 하는 이들에게 도움을 주고자 한다.
 
필자가 작성한 샘플코드의 화면 UI는 군더더기 없이 아래와 같다. 
HTTP 전송방식의 GET, POST를 적용한 예제를 위하여 간단하게 만들었다.
 
f0002937_591be18ec2fec.jpg

 

 
1.의 입력폼은 웹서버에 .jsp 파일과 입력폼을 통하여 웹서버에 요청하고 이를 웹서버에서 처리하여 결과 데이터를 클라이언트가 수신하여 웹 페이지에 표시하는 내용이다. 
 본 예제의 get_name_process.jsp 파일명과 입력폼에서 받은 텍스트("이대진")를 아래와 같이 요청 메시지로 구성하여 XMLHttpRequest에 전송하고 결과를 수신하는 구조이다.
 
 요청 메세지 : get_name_process.jsp?name=이대진  
 
 jsp에 대한 처리 구조는 아래 그림과 같다.  
 
f0002937_591be2e97abc0.jpg

 

< 출처 :  http://way2java.com/jsp/jsp-made-simple-how-jsp-works-or-what-is-jsp-architecture/ >
 
jsp에 대한 처리는 위 그림을 참조하기 바라며 본 예제에서는 1번 폼에서 위 처리를 거치게 된다.  
 
또한 "GET 방식" 버튼과 "POST 방식" 버튼을 각각 두어 XMLHttpRequest 에서의 활용법을 이해하도록 하였다. 
 
2.의 입력폼은 웹서버에 위치한 파일명을 입력하여 해당파일을 웹 브라우저에서 다운로드 하는 내용이다.
 
지금까지 샘플코드 동작에 대한 전반적 설명을 끝내고 이에 대한 소스코드는 아래와 같다.
 
  1. <form name="nameFrame" accept-charset="utf-8">
        <input type="text" name="name">
        <input type="button" value="이름 입력(GET 방식)" onclick="requestMessage( 'GET', 'get_name_process.jsp')">
        <input type="button" value="이름 입력(POST 방식)" onclick="requestMessage( 'POST', 'get_name_process.jsp')">
    </form>
    <div id="message1"></div>
  2. <form name="fileFrame" accept-charset="utf-8">
        <input type="text" name="name">
        <input type="button" value="파일명 입력" onclick="requestFile()">
    </form>
    <div id="message2"></div>
  3. <script>
        var httpRequest = (function(){
            var xmlhttp = null;
  4. function createRequest() {
        var http = null;
    
        if( window.XMLHttpRequest ){
            http = new XMLHttpRequest();
        } else if( window.ActiveXObject ){
            http = new ActiveXObject("Microsoft.XMLHTTP");      // IE를 위한 코드
        }
        return http;
    }
  5. function receiveEvent( propertyFunction, method, callback ) {
        if (xmlhttp.readyState != 4 ){
            if( propertyFunction == "onload") {
                alert("Error!! readyState Code : " + xmlhttp.readyState);
            } else {
                console.log("readyState Code : " + xmlhttp.readyState);
            }
            return;
        }
    
        if( xmlhttp.status == 200) {
            if (method == "HEAD") {
                alert(xmlhttp.getAllResponseHeaders());
                callback( xmlhttp );
            } else {
                callback( xmlhttp );
            }
        }
        else{
            alert( "Error!! status code : " + xmlhttp.status );
        }
    }
  6. function requestData( method, url, callback ){
        if( xmlhttp == null ){
            xmlhttp = createRequest();
        }
    
        var urlArray = null;
    
        if( method == "POST") {
            urlArray = url.split("?");
            xmlhttp.open(method, urlArray[0], true);
        } else {
            xmlhttp.open(method, url, true);
        }
    
        if( typeof( xmlhttp.onload ) != "undefined"){
            xmlhttp.onload = function() {
                receiveEvent( "onload", method, callback );
            }
        } else {
            xmlhttp.onreadystatechange = function () {
                receiveEvent( "onreadystatechange", method, callback );
            }
        }
    
        if( method == "POST") {
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlhttp.send( urlArray[1] );
        }else{
            xmlhttp.send(null)
        }
    }
  7. 
     
    return function( method, url, callback ){
    requestData( "HEAD", url, function (http) {
    http.responseAttachText = "Flie Len : " + parseInt( http.getResponseHeader("Content-Length"), 10)
    + ", Last Updated Date : " + http.getResponseHeader("Last-Modified")
    + ", Content type : " + http.getResponseHeader("Content-Type");
    requestData( method, url, callback );
    });
    }
    }());
  8. function showRequestResult( http ){
        document.getElementById("message1").innerHTML = http.responseText;
    }
    
  9. function showFileContents( http ){
        document.getElementById("message2").innerHTML = http.responseAttachText + "</br>" + http.responseText;
    }
  10. function requestMessage( method, url ){
        document.getElementById("message1").innerHTML = "";
        param = nameFrame.name.value;
        url = url + "?name=" + encodeURIComponent(param);   // 어떤 시스템에서나 읽을 수 있는 ascii 문자로 변환한
        httpRequest( method, url, showRequestResult );
    }
  11. function requestFile(){
        document.getElementById("message2").innerHTML = "";
        fileName = fileFrame.name.value;
        httpRequest( "GET", fileName, showFileContents );
    }
 
 1, 앞서 설명한 입력폼의 1.에 해당하는 html 코드이며 2.는 입력폼의 2에 해당하는 코드이다. 
 3. 즉시 실행함수의 형태로 XMLHttpRequest를 기반으로 데이터를 송수신 할 수 있는 httpRequest를 함수로 만드는 시작 코드이다. 
    즉시 실행함수의 특징을 활용한 클로저를 이용하여 변수 xmlhttp에 XMLHttpRequest를 생성하여 저장하도록 한다. 
    따라서 4.를 통하여 생성된 XMLHttpRequest는 한번 생성하면 xmlhttp 변수에 저장되므로 이를 지속적으로 활용하여 중복 생성과정이 없도록 한다. 
 4. 웹 브라우저에서 제공하는 XMLHttpRequest의 형태에 따라 new 연산자를 통하여 생성하고 이를 리턴한다. 
 5. XMLHttpRequest 가 전송할 데이터 처리가 완료되었을 때에 이를 수신하기 위한 함수로써 입력 파라미터는 각각 아래와 같다.
 propertyFunction : XMLHttpRequest의 onload 에서 호출되는 것인지 아니면 onreadystatechange 에서 호출되는 것인지를 구분하기 위한 구분자
 method : HEAD | GET | POST 방식 
 callback : 데이터 수신에 따라 처리해야 할 callback 함수 
 6. 웹 브라우저에서 서버로 데이터를 요청하기 위한 함수다.
    입력 파라미터는 아래와 같다.
   method : HEAD | GET | POST 방식 
   url : 웹서버내에 접근할 리소스 및 전달할 파라미터 
   callback : 데이터 수신시 처리할 callback 함수 
 7. 본 샘플에서 최종적으로 사용하게될 httpRequest의 함수 정의이다. 
    먼저 XMLHttpRequest.open 함수에 "HEAD"를 method로 전달하여 먼저 수신되는 정보를 확인하고 그 뒤에 "GET" 또는 "POST" 형태로 정보를 요청하는 구조이다. 
    파라미터로 받은 http에는 property 변수 responseAttachText를 정의하여 html 문서에 출력할 스트링을 저장함으로써 결과적으로 즉시실행함수에 정의된 xmlhttp 객체에 responseAttachText 가 추가된다. 
 
8. html 문서에 출력하는 함수
9. 8과 동일
10. get_name_process.jsp 파일과 입력된 텍스트 파라미터과 함께  XMLHttpRequest에 요청처리를 담당하는 함수로써 입력폼 1에서 버튼 클릭시 실행된다. 
11. 입력폼 2에서 버튼 클릭시 입력된 텍스트에 해당하는 파일을 웹서버로 부터 다운로드 하게 된다. 
 
위의 소스코드 1.에서의 get_name_process.jsp는 아래와 같으며 앞에서 언급한 jsp 처리 프로세스에 따라 결과를 리턴한다.  
 
<%@ page contentType="text/plain; charset=utf-8" %>
<%
request.setCharacterEncoding("utf-8");
String name = request.getParameter("name");
if( request.getMethod().equals("GET"))
    name = new String( name.getBytes("8859_1"), "UTF-8");
%>
Hi!! I like <%=name%>, Thanks for your kindness.
참고로 입력폼에서 받은 텍스트가 한글일 경우 깨짐현상이 발생하는데 이를 해결하기 위하여 위와 같이 getParameter를 통하여 받은 스트링을 UTF-8로 변환하는 코드가 있음을 알 수 있다.
 
 
 

 

 

 

 

 

 


번호 제목 글쓴이 날짜 조회 수
27 fetch() 함수 사용 예제 file 황제낙엽 2023.11.23 1
26 How to build a file upload service with vanilla JavaScript file 황제낙엽 2023.08.22 0
25 모바일 브라우저에서 file input element 를 이용하여 여러장의 이미지를 서버에 전송하려 할때 황제낙엽 2023.08.21 0
24 [URLSearchParams] URL 파라미터(매개변수) 값 가져오기 file 황제낙엽 2023.02.02 0
23 Fetch API (CORS 극복을 위한 노력) 황제낙엽 2021.12.05 26
22 두 서버의 자원을 접근하는 클라이언트 프레임웍(Next.js)에서의 CORS오류 file 황제낙엽 2021.12.05 231
21 CORS 의 내용과 이에 대한 우회 방안들 file 황제낙엽 2021.12.05 139
20 client 통신 기술 jquery ajax, fetch, axios 황제낙엽 2021.12.05 8
19 XMLHttpRequest Specification 황제낙엽 2021.04.29 11
18 XMLHttpRequest.timeout 황제낙엽 2018.11.03 248
» XMLHttpRequest 제대로 활용하기 file 황제낙엽 2017.08.01 58
16 Ajax (XMLHttpRequest) 샘플 황제낙엽 2017.08.01 93
15 Javascript CORS/XSS 극복하는(피하는) 방법 file 황제낙엽 2017.07.31 648
14 HTTP 접근 제어 (CORS) 황제낙엽 2017.05.29 125
13 CORS(Cross-Origin Resource Sharing) - 5 file 황제낙엽 2017.03.07 261
12 CORS(Cross-Origin Resource Sharing) - 4 file 황제낙엽 2017.03.07 874
11 CORS(Cross-Origin Resource Sharing) - 3 file 황제낙엽 2017.03.07 45
10 CORS(Cross-Origin Resource Sharing) - 2 황제낙엽 2017.03.07 24
9 CORS(Cross-Origin Resource Sharing) - 1 file 황제낙엽 2017.03.07 135
8 XMLHttpRequest.setRequestHeader 황제낙엽 2013.09.30 62