프린이8549 2024. 4. 29. 17:50

Ajax(Asynchronous JavaScript and XML; 비동기적 정보 교환 기법)

1.개념

Ajax 등장 이전의 데이터 요청 방식은 동기식 방법을 사용했다.

 

CF) 동기식 데이터 요청

  •  <html></html>로 끝나는 완전한 HTML 을 서버로부터 받아 웹페이지 전체를 다시 렌더링하는 방식으로 동작.
  • ex) a 태그, form submit 방식 등
  • 단점
    • 변경할 필요가 없는 부분까지 포함된 완전한 HTML 을 매번 재전송받기에 불필요한 데이터 통신 발생
    • 이를 처음부터 다시 렌더링하기 때문에 플리커 현상(화면 전환 시 화면이 순간적으로 깜빡임) 발생
    • 클라이언트와 서버와의 통신이 동기 방식으로 동작하기 때문에 서버로부터 응답이 있을 때까지 다음 처리는 블로킹됨(응답 시까지 대기)

Ajax는 전통적인 데이터 요청 방식과는 달리 자바스크립트를 이용해 브라우저가 서버에게 "비동기" 방식으로 데이터를 요청하고, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식이다.

 

 Ajax는 브라우저에서 제공하는 web API인 XMLHttpRequest 객체 기반으로 동작하며  XMLHttpRequest는 HTTP 비동기 통신을 위한 메서드와 프로퍼티를 제공한다.

 

 Ajax의 등장으로 브라우저에서도 데스트톱 애플리케이션과 유사한 빠른 퍼포먼스와 부드러운 화면 전환 가능해졌다.

 

 우리가 흔히 웹에서 관찰할 수 있는 실시간 검색어, 검색어 자동완성, 아이디 중복 체크, 찜하기, 팔로우, 추천, 댓글, 무한 스크롤 등의 기능들은 모두 Ajax를 활용한 결과물들이라고 할 수 있다

.

한편, 전통적인 방식과 비교했을 때 Ajax의 장점은 다음과 같다.

  1. 변경 부분 갱신에 필요한 데이터만 전송받기 때문에 불필요한 데이터 통신 미발생
  2. 변경할 필요가 없는 부분은 렌더링하지 않기 때문에 플리커 현상 미발생
  3. 비동기 방식으로 동작하기 때문에 서버에게 요청을 보낸 이후 블로킹 미발생

그러나 Ajax가 지닌 단점 역시 존재하는 데

  1. 현재 페이지에 지속적으로 리소스가 쌓임에 따라 페이지 속도 저하 가능
  2. 에러 발생 시 디버깅 곤란
  3. 응답 데이터에 대해 현재 페이지에서 새로운 요소를 만들어 지정해줘야 함(dom을 개발자가 직접 컨트롤해야함)

 

2. 사용 방법

 Ajax 는 순수 자바스크립트 방식(XMLHttpRequest)를 활용한 방법과 Jquery 를 사용한 방식이 있다.

본 글에서는 Jquery를 사용한 방법을 살펴보고자 한다.

 Jquery를 활용한 ajax 구현틀은 아래와 같다.

<Jquery 방식>
$.ajax({
    속성 : 값,
    속성 : 값,
    속성 : 값,
    .
    .
    .
});

 

 이 때 중괄호 내에 들어가는 주요 속성 / 부가적인 속성에 대해 살펴보자면,

 

 주요 속성

  • url
    • 요청할 url(필수 속성)
  • type | method
    • 요청 전송 방식(get | post)
  • data
    • 요청시 전달할 값
  • success
    • ajax 요청 성공시 실행할 함수 정의
  • error
    • ajax 요청 실패시 실행할 함수 정의
  • complete
    • ajax 요청 성공 여부와 관계없이 무조건 실행할 함수

부가 속성

  • async
    • 서버와의 비동기 처리 방식 설정 여부(기본값 true)
  • contentType
    • request의 데이터 인코딩 방식 정의(보내는 쪽의 데이터 인코딩)
  • dataType
    • 서버에서  response 로 오는 데이터의 타입 설정, 값이 없을 시 임의로 판단함
    • ex) xml, json, script, html, text
  • accept
    • 파라미터의 타입 설정(사용자 특화된 파라미터 타입 설정 가능)
  • beforeSend
    • ajax 요청 전 실행되는 이벤트 callback 함수(데이터 가공 및 header 관련 설정)
  • cache
    • 요청 및 결과값을 scope 에서 갖고 있지 않도록 하는 것
  • contents
    • Jquery 에서 response 의 데이터를 파싱하는 방식 정의
  • context
    • Ajax 메소드 내 모든 영역에서 파싱 방식 정의
  • crossDomain
    • 타 도메인 호출 가능 여부 설정(기본값 false)
  • dataFilter
    • response 를 받았을 시 정상적인 값을 return 할 수 있도록 데이터와 데이터 타입 설정
  • timeout
    • 서버 요청 시 응답 대기 시간
<h3>버튼 클릭 시 POST 방식으로 서버에 여러 개의 데이터 전송 및 응답</h3>
이름 : <input type="text" id="input1">
나이 : <input type="number" id="input2">
<button onclick="test()">전송</button>

<script>
	function test(){
    // 요청 보낼 url http://localhost:8001/kh/jqAjax.do
    // name값과 age값을 보내서 post요청
    $.ajax({
    	type : "POST",
        url : "http://localhost:8001/kh/jqAjax.do",
        data : {
        	name : $("#input1").val(),
            age : document.getElementById("input2").value
        },
        success: function(res){
        	console.log("응답: ");
            console.log(JSON.parse(res))
        },
        error: function(){
        	console.log("요청실패");
        }
     });
    }
</script>

 

 

위 요청을 받아 응답해줄 서블릿 컨트롤러의 코드는 아래와 같다.

package com.kh.common;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;
import com.kh.member.model.vo.Member;

/**
 * Servlet implementation class AjaxTextController
 */
@WebServlet("/jqAjax.do")
public class AjaxTextController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public AjaxTextController() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		
		//여러개를 응답하고싶지만 할 수 없다.
		//response.getWriter().print(name);
		//response.getWriter().print(age);
		
		/*
		 * JSON(자바스크립트에서 객체를 표기했던 방법, 실제로는 파일형식을 의미한다)
		 * ajax틍신시 데이터전송에 가장 많이 사용되는 포맷형식중 하나
		 * 
		 * {key:value, key:value ...} => JSONObject
		 * [value, value, value...] => JSONArray
		 */
		
//		JSONArray jArr = new JSONArray();
//		jArr.add(name);
//		jArr.add(age);
//		
//		response.setContentType("text/html; charset=UTF-8");
//		response.getWriter().print(jArr);
		
//		JSONObject jobj = new JSONObject(); // {}
//		jobj.put("name", name); // {name : 김개똥}
//		jobj.put("age", age); // {name : 김개똥, age : 61}
//	
//		response.setContentType("text/html; charset=UTF-8");
//		response.getWriter().print(jobj);
		
		ArrayList<Member> list = new ArrayList<>();
		list.add(new Member(1, "김개똥", "01012345678"));
		list.add(new Member(2, "최개똥", "01011112222"));
		list.add(new Member(3, "이개똥", "01033334444"));
		
//		JSONArray jArr = new JSONArray();
//		for (Member m : list) {
//			JSONObject jobj = new JSONObject();
//			jobj.put("userNo", m.getUserNo());
//			jobj.put("userName", m.getUserName());
//			jobj.put("phone", m.getPhone());
//			
//			jArr.add(jobj);
//		}
//		
//		response.setContentType("text/html; charset=UTF-8");
//		response.getWriter().print(jArr);
		
		response.setContentType("text/html; charset=UTF-8");
		new Gson().toJson(list, response.getWriter());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}