카테고리 없음

[Javascript] AXIOS 사용하여 Flask와 통신 - JSON, FormData 전송

코딩하기싫어근데취직은해야함 2025. 1. 13. 18:49

AXIOS는 Javascript와 Flask 사이에 데이터를 주고 받는 AJAX 통신 방식 중 하나이다.

 

1. JSON 데이터 전송

AXIOS 통신은 자동으로 데이터를 JSON 형식으로 변환시켜 준다. JSON은 {key: vaue} 배열로 형식이 간단하여 데이터를 읽고 쓰기 쉽다. HTML에서 user-email 값을 받아와 JSON 형식으로 자동으로 변환하여 Flask 서버로 전달할 수 있다. Fetch API를 사용한다면 수동으로 JSON.stringify()을 사용하여 변환해야 한다. 

<HTML>

<div class="form-group">
	<label for="user-email">이메일</label>
	<div class="email-form">
		<input type="email" id="user-email" name="user-email" placeholder="Email" required>
		<button type="button" id="confirm-email">중복 확인</button>
	</div>
	<p id="email-result"></p>
</div>

 

<Javascript>

confirm-email 버튼을 클릭하면 함수가 실행된다. 이메일 형식 검증 후, 이메일 형식이 올바르지 않으면 텍스트를 띄우고 함수가 종료된다. 검증이 통과되면, AXIOS 통신(POST)을 시작하여 JSON 형식으로 데이터를 Flask에 전송한다. 플라스크에서 처리 후 결과가 돌아오면 이를 email-result에 반영한다.

// comfirm email
document.getElementById('confirm-email').addEventListener('click', function(e) {
    e.preventDefault();

    const userEmail = document.getElementById('user-email').value;
    const emailResult = document.getElementById('email-result');
    
    // 이메일 형식 검증을 위한 정규표현식
    const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;

    if (!emailRegex.test(userEmail)) {
        emailResult.textContent = '올바른 이메일 형식이 아닙니다';
        emailResult.style.color = 'red';
        return;
    }

    axios.post('/confirm_email', {
        userEmail: userEmail
    })
    .then(function(response) {
        if (response.data.available) {
            emailResult.textContent = "사용 가능한 이메일입니다.";
            emailResult.style.color = 'green';
        }
        else {
            emailResult.textContent = "이미 등록된 이메일입니다.";
            emailResult.style.color = 'red';
        }
    })
    .catch(function(error) {
        console.error('에러 발생: ', error);
    });

});

<Flask>

Flask는 데이터를 JSON 형식으로 전달받는다. User 테이블에 있는 이메일과 비교하여 이미 존재하는 이메일일 경우 available을 False로, 존재하지 않으면 True를 반환한다.

@api.route('/confirm_email', methods=['POST'])
def confirm_email():
    data = request.json
    user_email = data.get('userEmail')

    user = User.query.filter_by(email=user_email).first()
    if user:
        return jsonify({
            'available' : False
        })
    else:
        return jsonify({
            'available' : True
        })

 

2. FormData 데이터 전송

전송할 데이터가 적다면 1번 방식을 써도 어려움이 없지만, 폼에 데이터가 많을 경우 하나하나 JSON으로 변환하기 귀찮다. 이럴 때는 FormData로 전송하면 한번에 처리할 수 있다.

<HTML>

<form class="signup-form" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="user-email">이메일</label>
        <div class="email-form">
            <input type="email" id="user-email" name="user-email" placeholder="Email" required>
            <button type="button" id="confirm-email">중복 확인</button>
        </div>
        <p id="email-result"></p>
    </div>
    <div class="form-group">
        <label for="user-pwd">비밀번호</label>
        <input type="password" name="user-pwd" placeholder="Password" required>
    </div>
    <div class="form-group">
        <label for="user-repwd">비밀번호 확인</label>
        <input type="password" name="user-repwd" placeholder="Comfirm password" required>
        <p id="pwd-result"></p>
    </div>
    <div class="form-group">
        <label for="user-phone">휴대폰 번호</label>
        <input type="tel" name="user-phone" placeholder="Phone number" required>
        <p id="phone-result"></p>
    </div>
    <p id="warning-message" style="color: red; display: none">모든 필드를 입력해주세요.</p>
    <div class="form-group">
        <label for="user-birth">생년월일</label>
        <input type="date" max="9999-12-31" name="user-birth" class="user-birth" placeholder="Birthday">
    </div>
    <div class="form-group">
        <label for="user-interest">관심</label>
        <input type="text" name="user-interest" placeholder="Interest">
    </div>
    <div class="form-group">
        <label for="user-work">직장, 학교</label>
        <input type="text" name="user-work" placeholder="Work">
    </div>
    <div class="form-group">
        <label for="user-location">위치</label>
        <input type="text" name="user-location" placeholder="Location">
    </div>
    <div class="form-group">
        <label for="user-website">웹사이트</label>
        <input type="text" name="user-website" placeholder="Website">
    </div>
    <div class="form-group">
        <div class="image-div">
            <img src="{{ url_for('static', filename='images/woman.png') }}" class="profile-image" id="profile-image">
        </div>
        <input type="file" id="image-input" name="user-image" style="display: none;" accept="image/*">
    </div>
    <div class="form-group">
        <label for="user-name">이름</label>
        <input type="text" name="user-name" placeholder="Name" required>
    </div>
    <div class="form-group">
        <label for="user-description">설명</label>
        <input type="text" name="user-description" placeholder="Description">
    </div>
    <button type="submit" class="submit-button">가입하기</button>    
</form>

 

<Javascript>

new FormData로 FormData 객체를 생성해주면 해당 폼 내의 모든 필드 데이터들이 포함된다. FormData는 파일 등 다양한 데이터 형식을 포함할 수 있다. 이 formData를 axios.post에 인자로 전달해주면 모든 입력 필드의 데이터가 Flask로 전송된다. 

document.addEventListener('DOMContentLoaded', function() {
    document.querySelector('.signup-form').addEventListener('submit', function(e) {
        e.preventDefault();
        const formData = new FormData(this);

        axios.post('/register', formData)
        .then(function(response) {
            document.querySelector('.form-container').style.display = 'none';
            document.querySelector('.welcome-message').style.display = 'block';
            document.getElementById('welcome-name').textContent = response.data.name;
        })
        .catch(function(error) {
            console.error('Error: ', error);
        });
    });
});

 

<Flask>

request.form으로 데이터들을 전달 받을 수 있다. User 객체(models/model.py에서 저장해 놓은 모델)를 생성한 후 모두 인자로 전달해준다. add한 후 commit 해주면 User 테이블에 새로운 데이터가 삽입된 것을 확인할 수 있다. 

@api.route('/register', methods=['POST'])
def register():
    user_email = request.form['user-email']
    user_pwd = request.form['user-pwd']
    user_phone = request.form['user-phone']

    user_birth = request.form['user-birth']
    if (user_birth == ''):
        user_birth = None
    user_interest = request.form['user-interest']
    user_work = request.form['user-work']
    user_location = request.form['user-location']
    user_website = request.form['user-website']
    
    user_image = request.files['user-image']
    if user_image.filename == '':
        file_path = ''
    else:
        file_name = secure_filename(user_image.filename)
        file_path = os.path.join('app/static/images/profile', file_name)
        user_image.save(file_path)
        
    user_name = request.form['user-name']
    user_description = request.form['user-description']

    new_user = User(username=user_name,
                    email=user_email,
                    password=user_pwd,
                    phone=user_phone,
                    birth=user_birth,
                    interest=user_interest,
                    work=user_work,
                    location=user_location,
                    website=user_website,
                    description=user_description,
                    image_path=file_path)
    
    db.session.add(new_user)
    db.session.commit()

    return jsonify ({
        'name': user_name
    })