1. JQuerry

제이쿼리는 웹사이트에 자바스크립트를 쉽게 활용할 수 있도록 도와주는 오픈소스 기반의 자바스크립트 라이브러리이다. 제이쿼리를 활용하면 Ajax 응용 프로그램 및 플러그인을 빠르게 개발할 수 있다는 장점이 있다.

1-1) Import JQuerry

우선, JQuerry를 사용하기 위해서는 JQuerry의 js 코드를 불러와줘야 한다. html의 header 부분에 다음 코드를 삽입하여 jquerry를 불러와준다. 이때, slim 빌드를 사용하게 되면 $.ajax()를 사용할 수 없으니 AJAX를 사용하기 위해서는 slim을 뺀 빌드버전을 사용해야한다.

<script src="https://code.jquery.com/jquery-3.5.1.js"></script>


1-2) 요소값 변경 by using JQuerry

JQuerry를 사용하면 특정 요소값도 쉽게 변경할 수 있다.

  • div 내용 변경

    id가 test인 div 텍스트가 변경된다.

$('#test').html('원하는 텍스트 입력')
  • css 속성 변경

    body의 font-weight가 10px로 변경된다.

$('body').css('font-weight', '10px');
  • Example
<div align="center">
    <div id="text">input box에 text를 입력하고 변경 버튼을 눌러보세요</div>
    <input id="test_input" placeholder="text 입력"/>
    <button id="text_btn">변경</button>
    <button id="color_btn">색변경</button>
    <script>
        $("#color_btn").click(test2);        
        $("#text_btn").click(test);
        function test(){
            var text = document.getElementById('test_input').value;
            $("#text").html(text);
        };
        function test2(){
            $("#text").css('color','red');
        };        
    </script>
</div>
input box에 text를 입력하고 변경 버튼을 눌러보세요



2. AJAX

Asynchronous Javascript And XML의 줄임말로, 자바스크립트를 이용해 서버와 브라우저가 비동기적으로 데이터를 교환할 수 있게 하는 통신기능이다.

2-1) 동기식 vs 비동기식

사용자가 어떤 게시물의 추천 버튼을 누르는 상황을 가정해보자. 만약 이를 동기적으로 처리한다면, 해당 추천 버튼과 연결된 url을 호출한 뒤 뷰 함수에 정의된 기타 함수들을 처리한 후 html 템플릿이 출력된다. 이렇게 되면, 단순히 추천 버튼을 누른 것 뿐인데 웹페이지가 리로드 되면서 불필요한 리소스가 낭비된다. 리소스뿐만 아니라 사용자 입장에서도 이는 상당히 불편한 상황일 것이다. 같은 내용을 AJAX를 통해 비동기적으로 수행하면, JSON/XML 형태로 필요한 데이터만 받아 갱신하기 때문에 페이지가 갱신되지 않고, 불필요한 리소스를 절약할 수 있다. 또한, 사용자 입장에서도 훨씬 쾌적한 이용을 할 수 있을 것이다.

image


2-2) CSRF 사용 해제

우선, Django에서 AJAX를 이용해 데이터 교환을 하기 위해서는, Django의 CSRF(Cross Site Request Forgery 사이트 간 요청 위조) 보안 정책을 해결해야 한다. 방법은 3가지가 있다.

  • Decorator를 사용하여 특정 view에 csrf 적용해제

    방법은 가장 단순하지만 보안상 추천하지 않는 방법이다.

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def search(request):

    return HttpResponse('success')
  • html 파일 header부분에 csrf token 생성하기

    html header 부분에 해당 코드를 집어 넣으면 된다. Django 공식문서에서 권장하는 방법이지만 복잡하다.

<script>
  function getCookie(name) {
      var cookieValue = null;
      if (document.cookie && document.cookie !== '') {
          var cookies = document.cookie.split(';');
          for (var i = 0; i < cookies.length; i++) {
              var cookie = cookies[i].trim();
              // Does this cookie string begin with the name we want?
              if (cookie.substring(0, name.length + 1) === (name + '=')) {
                  cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                  break;
              }
          }
      }
      return cookieValue;
  }
  var csrftoken = getCookie('csrftoken');

  function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
  $.ajaxSetup({
      beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
              xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
      }
  });
</script>
  • 권장 방법

    ajax setup 해주는 부분만 넣어도 csrf 사용을 중단할 수 있다. 가장 간결하고 편하다.

<script>
  $.ajaxSetup({
    headers: { "X-CSRFToken": '{{csrf_token}}' }
  });
</script>


2-3) 문법

다음과 같은 문법으로 간단하게 사용할 수 있다.

$.ajax({
    type : 'POST',           // 타입 (get, post, put 등등)
    url : '/test',           // 요청할 서버url
    data : JSON.stringify({  // 보낼 데이터 (Object , String, Array)
      "no" : no,
      "name" : name,
      "nick" : nick
    }),
    success : function(result) { // 결과 성공 콜백함수
        console.log(result);
    },
    error : function(request, status, error) { // 결과 에러 콜백함수
        console.log(error)
    }
})



3. 예시 : 아이디 중복확인

3-1) 문제상황

다음과 같은 간단한 회원가입 폼이 있다고 해보자. 이 때, 사용자가 이메일을 입력하고 중복확인 버튼을 누르면, DB에 저장되어 있는 회원 정보와 일치하는 이메일이 있는지 확인하여 중복확인 결과를 출력하고자 한다.

<form name="signup_form" action="#" method="post">
    <div>
        <h3>회원가입 폼</h3>
    </div>
    <div>
        <input type="text" id="name" name="name" placeholder="이름을 입력하세요." />
    </div>
    <div>
        <input type="text" id="email" name="email" placeholder="이메일을 입력하세요." />
        <button type="button" id="email_btn" class="btn-secondary">중복확인</button>
    </div>
    <div>
        <button>회원가입</button>
    </div>    
</form>


3-2) URL, View 점의

POST 방식으로 넘겨줄 url을 정의해준다.

[urls.py]
(중략)

path('test', test, name='test'),

(중략)

해당 url을 받아줄 뷰 함수를 정의한다. DB에서 Users 모델을 불러와 일치하는 email을 가진 유저가 있는지 확인한다. 일치하는 유저의 유무에 따라 boolean 값을 dict에 저장하여 return 해준다.

[views.py]
from django.http import JsonResponse
from accounts.models import Users
import json

def signup_check(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        email = data['email']
        user = Users.objects.filter(email = email)

        # 일치하는 id가 있다면,
        if user:
            user_yn = False
        # 일치하는 id 없음
        else:
            user_yn = True

        return JsonResponse({'result':user_yn})


3-3) AJAX 코드 작성

특정 URL로 데이터를 POST하고, View에서 계산된 결과를 받아와 후처리하는 AJAX 코드를 작성해준다. email_btn을 클릭하는 이벤트가 발생하면, test URL로 email POST한다. 그 후 뷰 함수에서 계산된 결과에 따라 test div의 값과 css 속성을 변경한다.

<script>
    $(document).ready(function() {
        $("#email_btn").click(test);
    });

    function test(){
        var email = document.getElementById("email").value;

        $.ajax({
            type : 'POST',
            url : "{.% url 'test' %.}",
            data : JSON.stringify({
            'email' : email
            }),
            success : function(result) {
            console.log(result.result);
            if (result.result){
                $('#test').html('사용 가능한 ID입니다.');
                $('#test').css('color', 'blue');
            } else {
                $('#test').html('이미 아이디가 존재합니다.');
                $('#test').css('color', 'red');
            }
            },
            error : function(request, status, error) {
            console.log(error);
            };
        });
    }
</script>


3-4) 결과

DB에 존재하는 ID : test0, test1

회원가입 폼

댓글남기기