회원 가입 때, controller에서 사용자가 이미 DB에 있는 이메일이나 닉네임을 입력했을 때, status를 400으로 보내도록 설계를 했다. 하지만 사용자가 가입에 실패 할 때마다 페이지가 새로고침되고 입력했던 값이 전부 사라져서 너무 불편했다. 그래서 사용성을 높이기 위해, 사용자가 입력한 값은 살리면서 회원 가입 정보를 검증하는 코드를 작성하기로 했다.
첫 구상
- session storage를 사용해서 input 값을 비밀번호를 제외하고 전부 저장한다.
- server에서 status code가 400이 return 될경우 session storage에 저장한 값을 불러와 input에 뿌려준다.
- status가 200이면 db에 회원 정보를 저장하고 login페이지로 redirection을 한다.
일단 구상을 이루기 위해서 코드를 작성했다. session storage에 저장하는 것과 input에 그려주는 것은 쉽게 구현할 수 있었다.
const form = document.querySelector(".form_container form");
const inputs = form.querySelectorAll("input");
const button = form.querySelector("button");
function handleSessionStorage(e) {
inputs.forEach((value) => {
if (value.name !== "password" && value.name !== "password2") {
sessionStorage.setItem(value.name, value.value);
}
});
}
function paintInputValue() {
const data = Object.keys(sessionStorage);
for (let item of data) {
inputs.forEach((value) => {
if (value.name === item) {
value.value = sessionStorage.getItem(item);
}
});
}
}
if (form) {
button.addEventListener("click", handleSessionStorage);
paintInputValue()
}
그런데 문제는 server에서 status를 400으로 보낼 경우를 client에서 받아야하는데 어떻게 받아야할지 난감했다.
그러니까 request 요청이 단일이 아니라 두 갈래로 나뉘어있는게 문제였다. 이걸 어디서부터 설계를 해야할지 난감했다. 그래서 그냥 일단 어떻게 동작하는지만이라도 파악해보기 위해서 그냥 fetch로 post요청을 던졌다.
async function handleSessionStorage(e) {
e.preventDefault();
const request = await fetch("/join", {
method: "POST"
});
if (request.status === 400) {
inputs.forEach((value) => {
if (value.name !== "password" && value.name !== "password2") {
sessionStorage.setItem(value.name, value.value);
}
});
paintInputValue(request);
}
if (request.status === 200) {
console.log("hi");
}
}
function paintInputValue(request) {
if (request.status === 400) {
const data = Object.keys(sessionStorage);
for (let item of data) {
inputs.forEach((value) => {
if (value.name === item) {
value.value = sessionStorage.getItem(item);
}
});
}
}
}
일단 너무 당연하게도(?) 동작을 하긴 하지만 의도대로 되지 않았다. 일단 새로고침이 계속 된다. 그래서 버튼을 누를 때, 새로고침이 안되도록 막아버렸다.
async function handleSessionStorage(e) {
e.preventDefault();
const request = await fetch("/join", {
method: "POST"
});
........
그럼 request의 status 코드를 받을 수 있었다. 하지만 새로운 문제를 맞딱뜨렸다.
그래서 stackoverflow를 열심히 뒤적거렸다.
질문 : how to get http request from server to client javascript
아직 유의미한 대답은 찾지 못했다. 그래서 일단 다시 가설을 세워보기로했다.
재구상
- 그러면 comment를 설계 할 때, fetch를 사용해서 client와 server간에 소통을 했던 것처럼 JSON으로 값을 주고 받도록 설계를 변경한다.
- 그렇게 하면 status code를 client에 보낼 수 있다. 그러면 두 가지를 다 잡을 수 있을 수도 있다.
- 먼저 첫 번 째로 DB를 조회해서 이미 DB에 있는 unique한 값을 입력했는지 여부를 client로 보낼 수 있다. 그리고 validation 코드를 client 쪽에서 작성하여서 controller로 값이 넘어가기전에 그 값이 올바른 값인지 아닌지 검증할 수 있다.
- 그렇게 하면 굳이 session storage를 사용하지 않아도 사용자가 입력한 값이 사라지지는 않을 것이다.
- production level의 사이트에서 회원가입을 할 때, network 창이 어떤 값이 왔다 갔다 하는지를 검사해봐야겠다.