본문 바로가기
Java/web

[Web] Ajax 완벽 정리, 다양한 예제 포함

by Jayson Jeong 2022. 7. 15.

Ajax 데이터 보내고 받기, Ajax Controller 데이터 받기, Ajax 데이터 배열로 보내기 등 다양한 경우에 대해 예제를 통해 알아보겠다.

 

목차

  1. Ajax란?
  2. Ajax 기본
  3. Ajax 설정
  4. Ajax 메소드 종류
  5. Ajax 예제

 

1. Ajax란? 

Ajax는 Asynchronous JavaScript and XML의 약자로, 말 그대로 JavaScript와 XML을 이용한 비동기적 정보 교환 기법이다. 다만 요즘은 XML보다는 JSON을 주로 사용한다. 

브라우저의 XMLHttpRequest를 이용해 전체 페이지를 새로 가져오지 않고도 페이지 일부만을 변경할 수 있도록 javascript를 실행해 서버에 데이터만을 별도로 요청하는 기법이다.

HTTP 프로토콜을 이용한 비동기 통신이며 브라우저는 정적 HTML 파일과 CSS파일, 데이터를 어떻게 요청하면 되는지를 설명한 javascript를 통해 HTML,CSS를 이용해 골격을 먼저 형성하고 ajax 실행 부가 담긴 javascript 영역을 실행하여 데이터를 별도로 가져와 적절한 방법으로 데이터를 끼워 넣은 후 페이지를 로딩한다.

 

2. Ajax 기본

javascript에 작성해야 하는 Ajax를 실행하는 방법이다. jQuery를 사용하기 전에는 Ajax 사용법을 통해 바닐라-js에서 실행하였으나 jQuery 점유율이 올라가며 Ajax도 주로 jQuery를 이용해 실행한다.

jQuery 를 이용한 Ajax

$.ajax({
    url: '/perform/getRelayList.ajax',
    method: 'post',
    data : form,
    dataType : 'html',
    success: function (data, status, xhr) {
        console.log("data : : " + JSON.stringify(data));
        $("#search_result").empty();
        $("#search_result").replaceWith(data);
    },
    error: function (data, status, err) {
    },
    complete: function () {
        var total = $("#dataCount").val();
        $("#totalCount").text(addComma(total));
    }
});

 

jQuery없이 구성

function reqListener(e){
    console.log(e.currentTarget.response);
}

var xhr = new XMLHttpRequest() //xhr 생성

xhr.addEventListener("load", reqListener);
xhr.open("GET", "/jbground/list.do");
xhr.send();

또는

const xhr = new XMLHttpRequest() //객체 인스턴스 생성

function connect(){
    xhr.onreadystatechange = reply();
    xhr.open("GET", "/jbground/ajax/vo.do");
    xhr.send();
}

function reply(){
    if(xhr.readyState === 4){
        if(xhr.status === 200){
            console.log(xhr.response);
            const obj = JSON.parse(xhr.response);
            console.log(obj);
        }
    }
}

 

3. Ajax 설정

Ajax를 사용하기 위해 필수적으로 알아야 하는 설정값 들이 있다. 주로 자주 사용되는 설정값 위주로 알아보겠다.

$.ajax({
        url : '/ajax/sample.do',
        type : 'GET',
        dataType : "json",
        contentType:"application/json",
        data : {
        		seq : seq
        		, type : type
                },
        timeout: 10000,
        beforeSend:function(){
            $('#loading').removeClass('display-none');
        },
        success : function(data){
            console.log(data);
            
        },
        error : function(request, status, error){
            alert("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
            var err=JSON.parse(request.responseText);

            alert(err.resData[0].errorMsg);
                
            $('#loading').addClass('display-none');
        },
        complete:function(){
            $('#loading').addClass('display-none');
        }
});

 

자주 쓰이는 설정값

구분 정의
url ajax 요청할 매핑된 url 입력 -
type HTTP 통신의 종류를 설정. put, delete는 모든 브라우저에서 지원하는 것이 아니기 때문에 주의가 필요. 기본값(default) : get
get, post, delete, put
dataType ajax를 통해 리턴받을 데이터의 타입을 설정. 생략했을 경우는, jQuery이 MIME 타입 등을 보면서 자동으로 결정 xml, html, json, script, jsonp, text
contentType 기본값을 가장 많이 사용
기본값(default) : application/x-www-form-urlencoded; charset=UTF-8
-
timeout ajax가 호출된 시점부터 시간을 재서 요청이 초과될 경우 에러 등의 상태로 전환함
$.ajaxSetup()의 global timeout에 의해 override됨.
number(milli secs)
data URL 파라미터를 통해 보낼 데이터. 종류 : Object or String or Array
Object는 key:value set 객체여야 하며 value 영역이 array일 경우 jQuery가 serialize를 해줌. value 영역이 String이 아닌 경우 String으로 변환한 뒤 전송됨
-
beforeSend ajax 실행 시 요청이 전송되기 전에 실행되는 event 입니다. 반환값을 false 또는 jqXHR.abort();로 설정하면 ajax 전송을 취소할 수 있습니다. -
success ajax 통신이 성공했을 때 실행되는 콜백함수 -
error request가 실패했을 때 실행되는 콜백함수. cross-domain 요청이나 cross-domain의 jsonp 요청에는 작동하지 않는다. -
complete success나 error가 호출된 이후에 호출되는 콜백함수 -

 

4. Ajax 메소드 종류

이번 포스트에서는 대표적으로 사용되는 GET, POST, PUT, DELETE만 소개하겠다.

 

  • GET : 데이터를 읽거나 검색할 때 주로 사용되는 메소드
  • POST : 새로운 리소스를 생성할 때 주로 사용되는 메소드
  • PUT : 리소스를 생성/업데이트 할 때 주로 사용되는 메소드
  • DELTE : 지정된 리소스를 삭제할 때 주로 사용되는 메소드

더 다양한 HTTP 메소드와 REST api가 궁금하다면?

2022.08.16 - [java/web] - [Web] REST API 예제 포함

 

[Web] REST API 예제 포함

REST란? REST(Representational State Transfer)는 월드 와이드웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식으로 2000년 로이 필딩(R. Fielding)의 박사학위 논문(Architectural Styles an

jbground.tistory.com

 

 


5. Ajax 예제

Ajax를 사용하는 다양한 방법들을 다양한 예제를 통해 자세히 알아보도록 하겠다. 예제는 다음과 같은 순서로 설명되어 있으며 GET 방식을 기준으로 정리한 내용이다.

  1. 브라우저에서 데이터를 전송하는 다양한 방법들
  2. 서버에서 데이터를 받는 다양한 방법들
  3. 데이터 타입별 서버에서 데이터를 보내고 브라우저에서 받는 방법들

 

1. Web Browser → Server / 브라우저에서 서버로 보낼 때

1.1. jQuery의 ajax function을 이용한 방법

$.ajax({
    url: '/ajax/sample6.ajax',
    method: 'post',
    dataType : 'text',
    data : {'name' : 'ajax_value1'
            , 'age' : 'ajax_value2'
            , 'sex' : 'ajax_value3'
            , 'hp' : 'ajax_value4'
            , 'desc' : 'ajax_value5'},
    success: function (data) {
        
    }
});

$.ajax({
    url: '/ajax/sample6.ajax',
    method: 'post',
    dataType : 'text',
    data : {name : 'ajax_value1'
            , age : 'ajax_value2'
            , sex : 'ajax_value3'
            , hp : 'ajax_value4'
            , desc : 'ajax_value5'},
    success: function (data) {
        
    }
});

 

1.2. javascript Object를 Map 또는 Array로 이용하는 방법

const obj = {};
obj['name'] = 'obj_value1';
obj['age'] = 'obj_value2';
obj['sex'] = 'obj_value3';
obj['hp'] = 'obj_value4';
obj['desc'] = 'obj_value5';

//text
$.ajax({
    url: '/ajax/sample1.ajax',
    method: 'get',
    dataType : 'text',
    data : obj,
    success: function (data, status, xhr) {
        console.log(data);
    }
});

 

1.3. javascript의 Map 객체 또는 Array 객체를 이용한 방법

const map = new Map();
map.set('name', 'map_value1');
map.set('age', 'map_value2');
map.set('sex', 'map_value3');
map.set('hp', 'map_value4');
map.set('desc', 'map_value5');

map.entries();

var args = "";

var i = 0;
map.forEach((value, key)=>{
    if(i > 0){
        args += '&';
    }
    args += key + '=' + value;
    i++;
})


$.ajax({
    url: '/ajax/sample1.ajax',
    method: 'get',
    dataType : 'text',
    data : args,
    traditional : true,
    success: function (data, status, xhr) {
        console.log(data);
    }
});

※참고하면 좋을 블로그 https://shanepark.tistory.com/220

 

1.4. form/submit을 이용한 방법

<form name="form1" action="/ajax/sample7.ajax" method="post" onsubmit="doSubmit(this);return false;">
	<label for="name"> 이름 : </label>
    <input type="text" id="name" name="name">
    <label for="age"> 나이 : </label>
    <input type="text" id="age" name="age">
    <label for="sex"> 성별 : </label>
    <input type="text" id="sex" name="sex">
    <label for="hp"> 휴대전화 : </label>
    <input type="text" id="hp" name="hp">
    <label for="desc"> 기타 : </label>
    <input type="text" id="desc" name="desc">
    <button type="submit" id="submit">submit</button>
</form>

또는

function doSubmit(form){
	form.submit();
}

또는

function doSubmit(form){
	$.ajax({
            url: '/ajax/sample7.ajax',
            method: 'get',
            dataType : 'text',
            data : form,
            traditional : true,
            success: function (data, status, xhr) {
                console.log(data);
            }
	});
}

 

1.5. 배열 또는 리스트맵 형식을 이용한 방법

위에 소개한 방법들을 응용하면 맵과 배열을 통해 원하는 데이터를 다양한 형식으로 전송할 수 있다.

Map을 배열로 전송해서 List<Object>로 받을 수 있도록 하는 방법이나 특정 항목을 배열로 전송하여 복수의 데이터를 받을 수 있도록 하는 방법 등이 있다.

const nameList = ['A', 'B', 'C']; //배열 데이터

const userList = []; //List<Map> 또는 List<VO> 데이터
var data1 = {
    'name' : 'first_val1'
    , 'age' : 'first_val2'
    , 'sex' : 'first_val3'
    , 'hp' : 'first_val4'
    , 'desc' : 'first_val5'
};
var data2 = {
    'name' : 'second_val1'
    , 'age' : 'second_val2'
    , 'sex' : 'second_val3'
    , 'hp' : 'second_val4'
    , 'desc' : 'second_val5'
};
userList.push(data1);
userList.push(data2);

$.ajax({
    url: '/ajax/sample1.ajax',
    method: 'get',
    dataType : 'text',
    traditional : true,
    data : {
    		nameList : nameList
            , userList : JSON.stringify(userList)
    },
    success: function (data, status, xhr) {
        console.log(data);
    }
});

 


2. Web Browser → Server / 서버에서 수신할 때

서버. 즉, Controller에서 매핑된 ajax url을 통해 response를 제공할 때 데이터 송수신 방법에 대해 설명하겠다.

 

2.1. HttpServletRequest를 이용한 방법

Header에 데이터를 담아서 보내는 경우 HttpServletRequest에서 URL Parameter를 조회 할 수 있다.

HttpServletRequest.getParameter("key");

@RequestMapping(value = "/ajax/sample1.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample1(HttpServletRequest request, ModelMap model){
    
    String name = request.getParameter("name");
    String age = request.getParameter("age");
    String sex = request.getParameter("sex");
    String hp = request.getParameter("hp");
    String desc = request.getParameter("desc");
    
    logger.info("name : {}, age : {}, sex : {}, hp : {}, desc : {}", name, age, sex, hp, desc);
    
    return "\"result\":\"ok\"";
}

 

2.2. Spring Framework의 @RequestParam 어노테이션을 이용한 방법

@RequestParam을 이용하면 URL Parameter의 값을 설정한 객체에 담을 수 있다.

@RequestMapping(value = "/ajax/sample2.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample2(@RequestParam String name
                    , @RequestParam String age
                    , @RequestParam String sex
                    , @RequestParam String hp
                    , @RequestParam String desc
                    , HttpServletRequest request, ModelMap model){

	logger.info("name : {}, age : {}, sex : {}, hp : {}, desc : {}", name, age, sex, hp, desc);

	return "\"result\":\"ok\"";
}

 

2.3. @RequestParam 어노테이션을 이용하여 Map or List에 담는 방법

@RequestParam을 응용한 방법으로 자바의 Map 또는 List에 담아서 사용할 수 있다.

@RequestMapping(value = "/ajax/sample3.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample3(@RequestParam Map<String, String> param, HttpServletRequest request, ModelMap model){
    
    String name = param.get("name");
    String age = param.get("age");
    String sex = param.get("sex");
    String hp = param.get("hp");
    String desc = param.get("desc");

    logger.info("name : {}, age : {}, sex : {}, hp : {}, desc : {}", name, age, sex, hp, desc);
    
    return "\"result\":\"ok\"";
}

 

2.4. @ModelAttribute 어노테이션을 통해 VO를 이용한 방법

@ModelAttribute 어노테이션을 이용해 미리 만들어 둔 VO 객체에 값을 담아서 사용할 수 있다.

@RequestMapping(value = "/ajax/sample4.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample4(@ModelAttribute User user, HttpServletRequest request, ModelMap model){

    String name = user.getName();
    String age = user.getAge();
    String sex = user.getSex();
    String hp = user.getHp();
    String desc = user.getDesc();

    logger.info("name : {}, age : {}, sex : {}, hp : {}, desc : {}", name, age, sex, hp, desc);
    return "\"result\":\"ok\"";
}

 

2.5. 배열 또는 맵 형식으로 데이터를 받았을 경우

배열로 된 값을 받거나 Web Browser에서 List<Map> 형식으로 데이터를 보낼 경우 서버에서 해당 데이터를 파싱할 때 신경써야 하는 부분이 몇 가지 있다. 

우선 ajax의 traditional 유무이다. traditional 옵션 유무에 따라 전송되는 데이터의 키 값이 변경될 수 있다. 

true false
arr=val1&arr=val2&arr=val3 arr[]=val1&arr[]=val2&arr[]=val3

그렇기 때문에 traditional=false일 경우 서버에도 별도로 key[] 라고 입력하여 배열 형식임을 알려주어야 한다. 

true일 경우는 별도로 입력할 필요 없음

List<VO> 구조일 경우에는 json string으로 데이터를 받아 ObjectMapper를 통해 파싱을 진행해주면 된다.

 

@RequestMapping(value = "/ajax/sample6.ajax", method = RequestMethod.POST)
@ResponseBody
public String sample6(@RequestParam(value = "nameList[]") List<String> nameList
                     , @RequestParam(value = "nameList") String[] nameArr
                      , @RequestParam(value = "userList") String userList
                , HttpServletRequest request, ModelMap model) throws JsonProcessingException {

    ObjectMapper mapper = new ObjectMapper();
    List<User> users = mapper.readValue(users, new TypeReference<List<User>>() {});

    logger.info(nameList.toString());
    logger.info(users.toString());


    return "\"result\":\"ok\"";
}

 


3. Server → Web Browser/서버에서 브라우저로 보낼 때 데이터 타입 별

3.1. xml

server

@RequestMapping(value = "/datatype/sample1.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample1(HttpServletRequest request, ModelMap model){
    Document document = getOrderListXml();

    XMLOutputter xmlOut = new XMLOutputter();

    return xmlOut.outputString(document);
}


public Document getOrderListXml(){
    List<Order> orderList = getOrderList();
    Document document = new Document();
    Element root=new Element("orderList");
    document.setRootElement(root);

    for (Order order : orderList) {
        Element orderElement = new Element("order");

        Element id = new Element("id");
        id.addContent(String.valueOf(order.getId()));
        orderElement.addContent(id);

        Element title = new Element("title");
        title.addContent(String.valueOf(order.getTitle()));
        orderElement.addContent(title);

        Element desc = new Element("desc");
        desc.addContent(String.valueOf(order.getDesc()));
        orderElement.addContent(desc);

        root.addContent(orderElement);
    }

    return document;
}

browser

$.ajax({
    url: '/datatype/sample1.ajax',
    method: 'get',
    dataType : 'xml',
    success: function (data, status, xhr) {
        console.log('xml-----------------')
        console.log(data);
        var dom = xhr.responseXML;
        var order = dom.getElementsByTagName("order");
        var title = order[0].childNodes[0].nodeValue;
    },
    error: function (data, status, err) {

    },
    complete: function () {

    }
});

 

3.2. json

server

@RequestMapping(value = "/datatype/sample2.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample2(HttpServletRequest request, HttpServletResponse response) throws IOException {

    JSONObject root = orderService.getOrderListJson();
    List<Order> or = orderService.getOrderList();
    ObjectMapper mapper = new ObjectMapper();
    String s = mapper.writeValueAsString(or);
    //
    return s;
}

browser

$.ajax({
    url: '/datatype/sample2.ajax',
    method: 'GET',
    dataType : 'json',
    contentType : "application/x-www-form-urlencoded; charset=UTF-8",
    success: function (data, status, xhr) {
        console.log('json-----------------')
        console.log(data);
        for(var i = 0; i<data.length; i++){
            console.log(data[i].id);
            console.log(data[i].title);
            console.log(data[i].desc);
        }
    },
    error: function (data, status, err) {

    },
    complete: function () {

    }
});

 

3.3. html

server

@RequestMapping(value = "/datatype/sample3.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample3(HttpServletRequest request, ModelMap model){
    return "thymeleaf/jbground/type_sample :: #test";
}

browser

$.ajax({
    url: '/datatype/sample3.ajax',
    method: 'get',
    dataType : 'html',
    success: function (data, status, xhr) {
        console.log('html-----------------')
        console.log(data)
        $('#test').replaceAll(data)
    },
    error: function (data, status, err) {

    },
    complete: function () {

    }
});

 

3.4. script

browser

var url = "https://code.jquery.com/color/jquery.color-2.1.2.js";
$.getScript( url, function() {
  $( "#go" ).on( "click", function() {
    $( ".block" )
      .animate({
        backgroundColor: "rgb(255, 180, 180)"
      }, 1000 )
      .delay( 500 )
      .animate({
        backgroundColor: "olive"
      }, 1000 )
      .delay( 500 )
      .animate({
        backgroundColor: "#00f"
      }, 1000 );
  });
});

 

3.5. jsonp

server

@RequestMapping(value = "/datatype/sample5.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample5(HttpServletRequest request, ModelMap model){
    String jsonpCallBack = request.getParameter("jsonpCallBack");
    String str = jsonpCallBack + "( {\"result\":\"ok\"} )";
    return str;
}

browser

$.ajax({
    url: '/datatype/sample5.ajax',
    method: 'get',
    dataType : 'jsonp',
    jsonp: "jsonpCallBack",
    success: function (data, status, xhr) {
        console.log('jsonp-----------------')
        console.log(data);
    },
    error: function (data, status, err) {

    },
    complete: function () {

    }
});

 

3.6. text

server

@RequestMapping(value = "/datatype/sample6.ajax", method = RequestMethod.GET)
@ResponseBody
public String sample6(HttpServletRequest request, ModelMap model){
    List<Order> orderList = orderService.getOrderList();

    return orderList.toString();
}

 

browser

$.ajax({
    url: '/datatype/sample6.ajax',
    method: 'get',
    dataType : 'text',
    success: function (data, status, xhr) {
        console.log('text-----------------')
        console.log(data);
    },
    error: function (data, status, err) {

    },
    complete: function () {

    }
});

 

 

Reference.

https://api.jquery.com/jquery.ajax/