<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 파일과 프론트에서 유효성 검사를 다루는 파일을 분리하여 작업했다.
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 검증을 통과하면 성공이고 아니면 무조건 실패라서 어떤 에러인지 확인할 수 없었다.
다음에는 클라이언트가 어떤 에러가 발생했는지 알 수 있도록 프론트에서 보여주는 방법을 찾아봐야겠다.