[Flask] AJAX 비동기 통신 코드 - 4


흐름 👀


  • 비밀번호 인증 -> 완료 시, 버튼 변경 (로그인 계정의 비밀번호와 비교)
  • 유효성검사 -> 완료 시, 버튼 변경
  • 전송하기 -> 1,2번 완료 시, flask에서 DB에 주민등록번호 추가/변경

결과화면 👀



1. HTML(전체) 📝

<!-- 네모 폼 출력 div -->
<div class="form_area">

  <!-- 아이디/비밀번호 area -->
  <div class="idpw_area">
    
    <!-- 아이디 area -->
    <h3><label for="username" class="margin25">아이디</label></h3>
    <input type="text" id="username" name="username" disabled value="{{ g_user }}">
    
    <!-- 비밀번호 area --><h3><label for="password" class="margin25">비밀번호</label></h3>
    <input type="password" id="password" name="password">
    <span class="error_box" id="pw_error">비밀번호가 맞지 않습니다.</span>
    
    <!-- 비밀번호 인증 area -->
    <div class="pwval_area">
      <h3><label for="pw_btn" id="pw_label">비밀번호 확인</label></h3>
      <input type="submit" id="pw_btn" name="pw_btn">
    </div>
  
  </div>

  <!-- 주민등록번호 area -->
  <div class="joo_area">
    <!-- 제목 area -->
    <div class="joo_area_label">
      <h3><label for="fir_joo">주민등록번호</label></h3>
      <span class="alert_box point_color">변환된 주민등록번호를 확인해주세요.</span>
    </div>
    
    <!-- 입력 area -->
    <div class="joo_area_input">
      <input type="text" id="fir_joo" name="fir_joo" value="{{ fir_joo }}"
             maxlength="6" onkeyup="this.value=this.value.replace(/[^0-9]/g,'');">
      <input type="text" id="sec_joo" name="sec_joo" value="{{ sec_joo }}"
             maxlength="7" onkeyup="this.value=this.value.replace(/[^0-9]/g,'');">
    </div>
    <span class="error_box" id="joo_error">주민등록번호가 유효하지 않습니다.</span>
    
    <!-- 유효성 검사 area -->
    <div class="val_area" >
      <h3><label for="val_btn" id="val_label">유효성검사</label></h3>
      <input type="submit" id="val_btn" name="val_btn">
    </div>
  </div>
</div>


2. JavaScript(전체) 📝

window.addEventListener('load', ()=> {

    // 비밀번호 비동기 통신 유효성 검사를 위한 변수선언
    const pw_input = document.querySelector("#password");
    const pw_btn = document.querySelector("#pw_btn");
    const pw_area = document.querySelector(".pwval_area");
    const pw_label = document.querySelector("#pw_label");
    const pw_error = document.querySelector("#pw_error");
    let pw_status = true; // 인증완료시 false 로 변경

    // 비밀번호 확인 버튼 클릭 시
    pw_btn.addEventListener('click', ()=> {
    // flask 에 전달할 input 값/종류를 JSON 형태로 선언
    const postdata = {
        'password':pw_input.value, 'kind': 'password'
        }
        $.ajax({
            type: 'POST',
            data: JSON.stringify(postdata),
            dataType : 'JSON',
            contentType: "application/json",
            success: function(result){
                // success -> 인증성공 Alert 출력
                successAlert();
                // 인증성공시 비활성화하기
                disabled(pw_input, false, pw_btn, pw_area, pw_label, pw_error);
                pw_status = false;
            },
            error: function(result){
                // error -> 인증실패 Alert 출력
                failedAlert();
                // 인증실패시 에러메시지 출력
                error_msg(pw_input, false, pw_error);
            }
        })
    });

    // 주민등록번호 유효성 검사를 위한 변수선언
    const joo_input1 = document.querySelector("#fir_joo");
    const joo_input2 = document.querySelector("#sec_joo");
    const joo_btn = document.querySelector("#val_btn");
    const joo_area = document.querySelector(".val_area");
    const joo_label = document.querySelector("#val_label");
    const joo_error = document.querySelector("#joo_error");
    let joo_status = true; // 인증완료시 false 로 변경

    // 주민등록번호 유효성 검사 버튼 클릭 시
    joo_btn.addEventListener('click', ()=> {
        document.querySelector(".alert_box").style.display = "none"; // 안내메시지 삭제
        let joomin = joo_input1.value + joo_input2.value; // 입력값 저장
        joomin = joomin.split(''); // 1자씩 저장
        const weight = [2,3,4,5,6,7,8,9,2,3,4,5]; // 가중치

        for(let i=0; i<joomin.length-1; i++){
            joomin[i] = joomin[i] * weight[i];
        }
        const last_joo = joomin[joomin.length-1];

        let sum = 0;
        for(let i=0; i<joomin.length-1; i++){
            sum += joomin[i];
        }
        sum = sum % 11;
        sum = 11 - sum;
        if (sum > 9){   // 9보다 크면 10으로 다시 나누고 나머지 저장
            sum = sum % 10;
        }

        // 주민등록번호가 유효할 때
        if(sum == last_joo){
            successAlert(); // 성공 알림창 함수 실행
            disabled(joo_input1, joo_input2, joo_btn, joo_area, joo_label, joo_error);
            joo_status = false;
            // flask 에 전달할 input 값/종류를 JSON 형태로 선언
            const postdata = {
                'kind': 'joo'
            }
            $.ajax({
                type: 'POST',
                data: JSON.stringify(postdata),
                dataType : 'JSON',
                contentType: "application/json",
                success: function(result){
                },
                error: function(result){
                    ajaxAlert(false); // 비동기 통신 실패시 알림창 실행
                }
            })
        }
        // 주민등록번호가 유효하지 않을 때
        else {
            failedAlert();  // 실패 알림창 함수 실행
            error_msg(joo_input1, joo_input2, joo_error); // 에러메시지 관련 함수 실행
        }


   });

   // 전송하기를 위한 변수 선언
   const sub_btn = document.querySelector("#submit");

   // 전송하기 버튼 클릭 시
   sub_btn.addEventListener('click', ()=> {
        // 두개의 인증 모두 했는지 확인
        if(pw_status==false && joo_status==false){
            // flask 에 전달할 input 값/종류를 JSON 형태로 선언
            const postdata = {
            'fir_joo': joo_input1.value, 'sec_joo': joo_input2.value, 'kind': 'submit'
            }
            $.ajax({
                type: 'POST',
                data: JSON.stringify(postdata),
                dataType : 'JSON',
                contentType: "application/json",
                success: function(result){
                    window.location.href = '/ocr/check/'
                },
                error: function(result){
                    ajaxAlert(false);  // 비동기 통신 실패시 알림창 실행
                }
            })
        }
        // 두개의 인증 모두 안했을 때
        else {
            subAlert();  // 전송 인증실패 알림창 함수 실행
        }
   });

    
    // 주민등록번호 앞자리 입력 시 자동 줄바꿈
    joo_input1.addEventListener('input', ()=>{
      if(joo_input1.value.length>5){
        joo_input2.focus();
        joo_input2.select();
      }
    });

    // 받은 변수를 비활성화 시키는 함수
    function disabled(input1, input2, btn, area, label, error){
        if(input2){ // 주민등록번호
            input1.disabled=true;
            input2.disabled=true;
        }
        else { // 비밀번호
            input1.disabled=true;
        }
        btn.disabled=true;
        area.disabled=true;
        error.style.display = "none";
        label.innerHTML = "인증완료";
        label.style.cursor = "default";
        area.style.color = "#3e6595";
        area.style.backgroundColor = "#f9f9f9";
        area.style.border = "0.8px solid #3e6595";
        area.style.cursor = "default";

    }
    // 비동기통신 에러시, 에러메시지 출력을 위한 함수
    function error_msg(input1, input2, error){
        if(input2){
            input1.value="";
            input2.value="";
        }
        else {
            input1.value="";
        }
        error.style.display = "flex";
    }
    // 성공 알림 함수
    function successAlert(){
        Swal.fire({
            icon: 'success',
            title: '인증성공',
            text: '인증되었습니다.',
            confirmButtonColor: '#2b70f8',
            width: '25rem',
        });
    }
    // 실패 알림 함수
    function failedAlert(){
        Swal.fire({
            icon: 'error',
            title: '인증실패',
            text: '다시 입력해주세요.',
            confirmButtonColor: '#2b70f8',
            width: '25rem',
        });
    }
    // 전송실패 알림 함수
    function subAlert(){
        Swal.fire({
            icon: 'error',
            title: '인증실패',
            text: '인증을 먼저 해주세요.',
            confirmButtonColor: '#2b70f8',
            width: '25rem',
        });
    }
    // 비동기 통신 알림 함수
    function ajaxAlert(text){
        if(text == true){
            Swal.fire({
            icon: 'success',
            title: 'Success',
            text: 'ajax success!',
            confirmButtonColor: '#2b70f8',
            width: '25rem',
            });
        }
        else {
            Swal.fire({
            icon: 'error',
            title: 'Fail',
            text: 'ajax failed',
            confirmButtonColor: '#2b70f8',
            width: '25rem',
            });
        }
    }
});

3. Python(FLASK) 📝

# 라우트함수 print() 선언
@bp.route('/print/', methods=['POST', 'GET'])
def print():
    if request.method == 'POST':
        user = User.query.filter_by(username=g.user.username).first()

        if request.get_json():  # 비동기 통신의 경우
            result = request.get_json()  # 비동기 통신 데이터 저장

            if result['kind'] == 'password':  # 데이터의 종류가 password 일 경우
                password = result['password']
                if check_password_hash(user.password, password):  # 입력받은 pw와 기존 user.pw 비교
                    return jsonify(result="success", data=result)
                else:
                    return jsonify(result="error", data=result), 500

            elif result['kind'] == 'joo':  # 데이터의 종류가 joo 일 경우
                return jsonify(result="success", data=result)

            elif result['kind'] == 'submit':  # 데이터의 종류가 submit 일 경우
                user.fir_joo = result['fir_joo']
                user.sec_joo = result['sec_joo']
                db.session.commit()
                return jsonify()

            else:
                return jsonify(result="error"), 500
      
      else: # 비동기 통신이 아닐 경우 생략
      	...
  • 비동기 통신이 아닐 경우 밑에 있는 함수는 관련이 없어서 생략했다.
  • 라이브러리도 생략했다.

좋은 웹페이지 즐겨찾기