TIL(44일차)

김규현·2022년 11월 5일
0

📝 오늘 배운 것

💡 JavaScript로 백엔드에 데이터 보내기(회원가입)

html

<h1>회원가입 페이지</h1>
    <form>
        <div class="mb-3">
            <label for="exampleInputEmail1" class="form-label">아이디</label>
            <input type="text" class="form-control" id="username" aria-describedby="emailHelp">
        </div>
        <div class="mb-3">
            <label for="exampleInputPassword1" class="form-label">비밀번호</label>
            <input type="password" class="form-control" id="password">
        </div>
        <div class="mb-3">
            <label for="exampleInputPassword1" class="form-label">비밀번호 재확인</label>
            <input type="password" class="form-control" id="password2">
        </div>
        <div class="file mb-3">
            <label class="img" for="inputGroupFile01" style="margin-bottom: 5px;">프로필 사진</label>
            <input type="file" class="form-control" id="profile_img">
        </div>
        <div class="mb-3">
            <label for="exampleInputEmail1" class="form-label">프로필 소개</label>
            <input type="text" class="form-control" id="introduce" aria-describedby="emailHelp">
        </div>
        <div class="mb-3">
            <label for="exampleInputEmail1" class="form-label">관심있는 장르</label>
            <input type="text" class="form-control" id="favorite" aria-describedby="emailHelp">
        </div>
        <button type="button" class="btn btn-primary" id='signupbtn' onclick="handleSignup()" style="display: block; width: 150px; margin: auto; margin-top: 50px;">가입하기</button>
    </form>

우선 코드가 길어져서 body 태그 안의 코드만 가져왔다.
html은 위에서 부터 아래로 읽기 때문에 script 참조는 body 아래에서 해주면 좋을 것 같다.
html 코드는 특별한 것은 없고 class는 css쪽에서 사용했고, id는 js에서 사용했다.
그리고 버튼에 onclick 이벤트를 두었고 백엔드에 데이터를 주고 받는 js 파일과 프론트에서 유효성 검사를 다루는 파일을 분리하여 작업했다.

javascript(백엔드용)

window.onload = () => {
    console.log('로딩 완료')
}
// 전역 변수 //
const backend_base_url = 'http://127.0.0.1:8000/'
const frontend_base_url = 'http://127.0.0.1:5500/'

async function handleSignup() {
    const username = document.getElementById('username').value
    const password = document.getElementById('password').value
    const profile_img = document.getElementById('profile_img').files[0]
    const introduce = document.getElementById('introduce').value
    const favorite = document.getElementById('favorite').value
    const formData = new FormData()
    formData.append("username", username)
    formData.append("password", password)
    formData.append("profile_img", profile_img)
    formData.append("introduce", introduce)
    formData.append("favorite", favorite)
    const response = await fetch('http://127.0.0.1:8000/users/sign-up/', {
        headers: {
        },
        method: 'POST',
        body: formData
    })
    console.log(response)

    if (response.status == 201) {
        alert('가입 완료!')
        window.location.replace(`${frontend_base_url}login.html`)
    } else {
        alert("잘못된 접근입니다.", response.status)
    }
}

우선 js파일이 html에서 잘 읽는지 보기 위해 window.onload로 실행되면 console.log를 찍어 연결 상태를 확인했다.
그 다음 백엔드 서버와 연결되어 있지 않기 때문에 localhost를 간편하게 쓰기 위해 변수에 담았다.

그리고 사용자가 정보를 입력하고 버튼을 눌렀을 때 handleSignup 함수가 실행되어 document.getElementById에 사용자가 입력한 input 박스의 값을 id로 가져와 각각의 변수에 담는다.

먼저 formData를 사용하지 않고 보냈을 때는 status 400 에러가 발생했다.
뭔가 이미지 파일 때문인 것 같아 찾아보니 fetch로 post 요청을 보낼 때 body에 formData 객체에 form/multipart 형태로 데이터를 전송해야 하는데 JSON.stringify로 JSON의 문자열로 보냈기 때문에 파일 데이터를 보낼 수가 없었다.

그래서 formData에 사용자의 입력 값을 받아 body에 실어주어서 fetch로 post 요청 후 response 값을 response 변수에 담아서 status 코드가 201(create)인 경우 가입완료 알럿 창과 함께 login 페이지로 이동시켜주었고, 그 외 다른 status 코드는 잘못된 접근이라는 알럿을 띄워준다.

여기서 한 가지 고민에 빠졌는데 만약 사용자가 입력한 값이 정규식을 통과한 후 요청을 보냈을 때 이미 가입된 user가 있거나, 접근할 수 없는 사용자가 접근하여 에러 코드를 내려받게 되면 status가 201이 아니기 때문에 잘못된 접근이라는 알럿이 뜨고, 사용자 입장에서는 어떤 문제로 가입이 되지 않는지 알 수가 없다.


백엔드에서도 성공(201) or 실패(400)로 코드를 내려주기 때문에 데이터가 정상적으로 들어와서 serializer 검증을 통과하면 성공이고 아니면 무조건 실패라서 어떤 에러인지 확인할 수 없었다.

다음에는 클라이언트가 어떤 에러가 발생했는지 알 수 있도록 프론트에서 보여주는 방법을 찾아봐야겠다.

profile
웹개발 회고록

0개의 댓글