TIL

1차 팀 프로젝트 / 이미지 문자열 변환 (1주차 - 화)

ImJaeOne 2024. 12. 24. 21:51

드디어 팀원들과 깃을 이용한 협업을 시작했습니다....!

 

저는 멤버 카드 Form을 만들었습니다. 처음에는 회원가입 기능을 생략하고 DB에 userId와 userPw를 미리 넣어놓은 채로 진행하려 했지만, 백엔드에 신경 쓰기보다는 프론트엔드 기능에 중점을 두기로 했습니다. 그래서 멤버 카드 생성과 회원 가입 기능을 함께 구현하기로 했습니다.

 

1. HTML

더보기
<form id="member__form">
            <div class="form__group">
                <label for="userId">아이디</label>
                <input type="text" id="userId" name="userId" placeholder="아이디를 입력해주세요">
            </div>
            <div class="form__group">
                <label for="userPw">비밀번호</label>
                <input type="password" id="userPw" name="userPw" placeholder="비밀번호를 입력해주세요">
            </div>
            <div class="form__group">
                <label for="photo">사진</label>
                <input type="file" id="photo" name="photo">
            </div>
            <div class="form__group">
                <label for="name">이름</label>
                <input type="text" id="name" name="name" placeholder="이름을 입력해주세요">
            </div>
            <div class="form__group">
                <label for="mbti">MBTI</label>
                <input type="text" id="mbti" name="mbti" placeholder="MBTI를 입력해주세요(4자 영어로)">
            </div>
            <div class="form__group">
                <label for="hobby">취미</label>
                <input type="text" id="hobby" name="hobby" placeholder="취미를 입력해주세요">
            </div>
            <div class="form__group">
                <label for="bio">자기소개</label>
                <textarea id="bio" name="bio" placeholder="자기소개를 입력해주세요"></textarea>
            </div>
            <div class="form__group" id="blog">
                <label for="blog__category">블로그</label>
                <div id="blog__info">
                    <select id="blog__category" name="blog__category">
                        <option selected>---</option>
                        <option>velog</option>
                        <option>tistory</option>
                    </select>
                    <input type="text" id="blog__name" name="blog__name" placeholder="블로그 주소를 입력해주세요">
                </div>
            </div>
            <div class="form__group">
                <label for="github">Github</label>
                <input type="text" id="github" name="github" placeholder="Github 주소를 입력해주세요">
            </div>
            <div class="form__group">
                <button type="submit" id="submit">제출</button>
            </div>
        </form>

form 태그로 묶어 데이터를 한 번에 불러올 수 있도록 처리하였습니다.


2. JS

1. 이미지 Base64 형식으로 변환하기

초기에는 Firebase Storage에 이미지를 저장하려 했지만, CORS 오류가 발생했습니다. 문제(유료 버전이라 안되는거였음 ㅜ)를 해결하기 위해, Firebase Storage 대신 DB에 이미지를 Base64 형식으로 저장하는 방식으로 변경했습니다.

function converFileToBase64(file) {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(reader.result);
        reader.onerror = (error) => reject(error);
        reader.readAsDataURL(file);
    })
}

 

FileReader API를 사용해 파일을 Base64 형식으로 변환하고, 변환된 데이터를 반환하는 converFileToBase64 함수를 작성했습니다. 이 방식은 파일을 문자열로 변환하여 Firebase Firestore에 저장할 수 있습니다.

 

2. 유효성 검사

폼 제출 시, 필수 입력값에 대한 유효성 검사를 추가했습니다. 값이 비어 있는 필드에는 알림을 띄우고 해당 필드에 포커스를 이동시키도록 구현했습니다.

function validationForm(formData) {
    const fields = [
        { id: 'userId', name: '아이디' },
        { id: 'userPw', name: '비밀번호' },
        { id: 'name', name: '이름' },
        { id: 'mbti', name: 'MBTI' },
        { id: 'hobby', name: '취미' },
        { id: 'bio', name: '자기소개' },
        { id: 'blog__category', name: '블로그 카테고리' },
        { id: 'blog__name', name: '블로그 주소' },
        { id: 'github', name: '깃허브 주소' },
    ];

    for (const field of fields) {
        if (!formData.get(`${field.id}`)) {
            alert(`${field.name}을 입력해주세요.`);
            document.getElementById(field.id).focus();
            return false;
        }
    }

    return true;
}

 

 

일단 유효성 검사는 데이터의 값이 없을 시 그 필드로 focus가 되도록 구현했습니다.

 

이렇게 해서 

 

데이터가 잘 들어오는 것까지 확인할 수 있습니다~!