Javasciprt

[ajax] Ajax를 통한 비동기 통신

씬프 2021. 8. 26. 13:00
반응형

웹 애플리케이션을 개발하다보면 한가지 기능을 수행하는데, 비효율적으로 동작하는 경우가 있다.

모든 비효율적 동작을 알 수 없고, 모두 효율적으로 해결할 수 없지만, 많이 알려진 것들은 배우고 활용할 필요가 있다.

 

Ajax의 비동기적 통신은 웹 애플리케이션에서 불필요한 리소스를 불러오지 않고

클라이언트와 서버가 통신할 수 있도록 돕는다.

 

1. Ajax 사용을 위해 jQuery 호출하기

먼저, jQuery를 사용해야 한다. (slim에서는 사용할 수 없었다. minified로 사용했다.)

<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>

 

2. Ajax의 사용

ajax는 javascript 파일에서 사용된다.

$.ajax({
  type: 'get',
  url: url,
  data: data,
  dataType: 'json',
  error: onError,
  success: onSuccess
})

function onError() {}

function onSuccess() {}

ajax에는 json 형식으로 정보가 전달된다.

type : 어떤 HTTP method를 사용할지

url : 요청할 url

data : 전달되는 data, 예를 들어 post 방식으로 form 데이터를 전달할 때, 담긴 내용을 data로 전달한다.

dataType : 서버로부터 받는 데이터의 타입을 정의한다.

error : 에러가 발생할 경우 실행되는 함수

success : 통신이 성공했을 때 실행되는 함수

 

3. Ajax 사용 예시 (댓글 추가)

Post 방식으로 댓글 form 데이터를 ajax로 비동기적 통신을 할 수 있다.

그렇게 되면 댓글이 달릴 때마다 전체 댓글을 다시 불러오지 않아도 된다.

template을 이용해 추가된 것과 같이 보이게 할 수 있다.

 

1) 댓글 form 양식 (html)

<form class="answer-write" action="/posts/<%= post.id %>/comments" method="POST" style="margin-top: 16px;">
  <div class="form-group">
    <textarea name="comment" class="form-control" id="comment" cols="30" rows="5" placeholder="Enter comment"></textarea>
  </div>
  <input type="submit" class="btn btn-primary"></input>
</form>

댓글을 작성할 수 있는 form 양식을 정의한다. 간단하게 textarea에 입력하고, submit 버튼만 구현했다.

 

2) ajax 정의 (js)

$(".answer-write input[type=submit]").click(addAnswer);

먼저, form 양식의 input의 click 이벤트가 발생했을 때, addAnswer 함수를 호출하는 리스너를 정의한다.

function addAnswer(e) {
  e.preventDefault();
  console.log('click');

  let queryString = $(".answer-write").serialize();
  console.log("query : " + queryString);

  let url = $(".answer-write").attr("action");
  console.log("url : " + url);

  $.ajax({
    type: 'post',
    url: url,
    data: queryString,
    dataType: 'json',
    error: onError,
    success: onSuccess
  });
}

리스너를 통해 호출된 addAnswer은 ajax를 호출하기 전, 필요한 데이터를 정의한다.

serialize() 함수를 통해 요청에 담길 data를 호출한다. 현재, form 데이터에서 comment가 데이터로 호출된다.

그리고, url 데이터를 attr("action")을 통해 form의 프로퍼티 중 action에 담긴 값을 가져온다.

 

이제 준비된 데이터를 통해 ajax로 비동기 통신을 시도한다.

 

성공할 경우 댓글이 달릴 수 있도록 onSuccess에 댓글이 달리는 로직을 구현한다.

function onSuccess(data, status) {
  let template = `
  <div class="card" style="margin-top: 8px;">
    <div class="card-body">
      <p class="card-text">${data.content}</p>
      <p class="card-text">${data.userId}</p>
      <p class="card-text">${data.created}</p>
    </div>

    <div class="btn-group">
      <a href="/posts/${data.postId}/comments/${data.commentId}" class="btn btn-primary" style="margin: 4px">수정</a>
      <form action="/posts/${data.postId}/comments/${data.commentId}" method="POST" style="margin: 4px" name="deleteComment">
        <input type="hidden" name="_method" value="DELETE" />
        <input type="submit" class="btn btn-secondary delete" value="삭제" onclick="removeCheck(deleteComment)" />
      </form>
    </div>
  </div>`;
  
  $('.comment').append(template);
  $('.answer-write textarea').val('');
}

class가 comment인 dom 아래에 위에 정의한 template을 추가하도록 한다. 그리고 textarea의 값은 비워준다.

현재 Javascript 코드와 html 코드만 정의되어 있지만, 서버와 통신하기 위한 컨트롤러, 리포지토리도 함께 백엔드 쪽에서 구성되어 있어야 동작한다.

 

4. 정리

ajax는 클라이언트에서 서버로 통신할 때, 비동기적으로 통신할 수 있게 한다.

이는 불필요한 데이터를 서버에서 호출하지 않아도 되며, 클라이언트가 보는 화면의 변화 없이 서버와 통신할 수 있다.