Skip to content

Latest commit

 

History

History
128 lines (117 loc) · 6.08 KB

2024-12-05.md

File metadata and controls

128 lines (117 loc) · 6.08 KB

📝 Today I Learn

🗓️ 날짜: 2024-12-05

🙏🏻 스크럼

  • 학습 목표 1 : 프론트엔드 JS 코드 - Fetch (로그인)
  • 학습 목표 2 : 프론트엔드 JS 코드 - Fetch (회원 가입)

# 로그인 Fetch

| 엔드포인트

fetch('/api/users/login', {})
  • 일반적인 웹사이트 URL과는 목적과 용도가 다름, 클라이언트가 서버에 요청을 보내기 위해 사용되는 API 엔드포인트 (데이터를 주고 받는 데 사용)
  • api는 보통 서버에서 데이터를 제공하는 경로임을 표시해 API 요청과 일반 웹페이지를 구분하기 위해 붙이곤 함
  • 의미가 분명하고 요청 목적을 명확히 드러내는 것이 좋으며, RESTful 규칙을 따르는 경우가 많음

| HTTP 요청 속성

fetch('/api/users/login', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email, password })
})
  • method: 요청 동작 정의 (기본 값 GET, method 생략 가능)
  • headers: 서버에 전달하는 추가 정보 (클-서 어떻게 소통할지 알려줌)
    • Content-Type: 요청 데이터 형식 지정 (기본적으로 많이 사용)
      • application/json: JSON 형식의 데이터를 전송할 때 사용
    • Authorization: 인증 토큰 또는 인증 정보
    • Accept: 클라이언트가 받을 수 있는 응답 데이터 형식
    • User-Agent: 요청 보낸 클라이언트 정보
  • body: 서버에 보낼 데이터 담음 (GET 요청에는 body 포함 안됨, 규칙상 허용 X)
    • 일반적으로 JSON 형식 사용, 이를 JSON.stringfy로 JavaScript 객체를 JSON 문자열로 변환

| 서버 응답 처리

.then(response => {
    if (!response.ok) {
        throw new Error(`서버 에러 발생: ${response.status}`);
    }
    return response.json();
    })
.then(data => {
    if (data.token) {
        // 로그인 성공 시 
        localStorage.setItem('authToken', data.token);
        window.location.href = '/posts';
    } else {
        // 로그인 실패 시 
        helperText.textContent = '*아이디 또는 비밀번호를 확인해주세요.';
        helperText.style.display = 'block';
    }
})
.catch(error => {
    console.error('로그인 오류:', error);
})
  • then(): Promise의 성공 결과를 처리 (체인 패턴: .then 여러번 연결해 단계별로 데이터 처리)
    • response.ok: HTTP 상태 코드가 200~299 사이(정상적인 응답)인지 확인
    • response.json(): 서버에서 반환된 데이터를 JSON 형식으로 파싱하여 다음 .then으로 넘김 (서버가 반환하는 JSON 응답은 텍스트로 인코딩된 상태)
    • data.token: 서버로부터 받은 응답 데이터 중 token 값이 있는지 확인
    • localStorage.setItem('authToken', data.token): 브라우저 localStorage에 authToken 키로 받은 토큰 값을 저장 (이후 API 호출 시 인증 정보로 사용 가능)
  • catch: 앞 단계에서 발생한 모든 오류 처리

# 회원 가입 Fetch

| 쿼리 문자열, 데이터 인코딩

fetch(`/api/users/email/check?email=${encodeURIComponent(email)}`, {})
  • ? 이후는 쿼리 문자열(Query String), 서버로 데이터 전달 시 사용
  • encodeURIComponent(): URL에 포함될 데이터를 안전하게 인코딩 (이메일 주소 같은 값에는 특수문자가 포함될 수 있으므로 이를 URL에서 사용할 수 있도록 변환)
    • GET 요청으로 읽기 작업을 했으므로, 이메일 정보를 쿼리 문자열로 제공함으로써 본문(body)을 포함하지 않고 서버는 클라이언트가 요청한 내용을 명확히 알 수 있음

| 헤더가 없는 경우

fetch(`/api/users/email/check?email=${encodeURIComponent(email)}`, {
    method: 'GET',
})

fetch('/api/users/signup', {
    method: 'POST',
    body: formData 
})
  • GET은 요청 본문을 포함하지 않아 Content-Type 헤더가 필요없음 (데이터 형식을 지정할 필요가 없음)
  • POST는 formData를 전송할 때 Content-Type 헤더를 자동으로 추가함 <헤더를 명시적으로 추가해야하는 경우>
  • JSON 데이터를 보낼 때
  • 인증 정보를 포함해야할 때

| 응답 객체 속성

  • 성공 여부: success, status, result
  • 메시지: message, error, description
  • 데이터: data, items, result
  • 기타 정보: token (인증 토큰), count (데이터 개수), exists (존재 여부)

| FormData 객체

// 회원가입 데이터를 서버로 전송
const formData = new FormData();
formData.append('profile_photo', profilePhotoInput.files[0]);
formData.append('email', emailInput.value.trim());
formData.append('password', passwordInput.value);
formData.append('nickname', nicknameInput.value.trim());
  • HTML 폼 데이터를 키-값 쌍 형태로 쉽게 다룰 수 있는 JavaScript 객체 (주로 파일 업로드, 폼 데이터 전송에 사용) <FormData 사용 이유>
  • 파일 업로드: 일반적인 폼에서는 파일을 전송할 때 multipart/form-data 형식으로 데이터를 전송해야함, FormData 객체는 이 형식을 자동으로 처리
  • 편리한 데이터 관리: 각 입력 필드의 데이터를 별도로 관리하지 않고, FormData에 추가하는 방식으로 데이터를 모아 서버로 전송 가능

✊🏻 오늘의 도전 과제와 해결 방법

  • 도전 과제 1: TIL 작성
  • 도전 과제 2: Fetch에 대해 이해하기
  • 도전 과제 3: 프론트엔드 JS 코드 - Fetch (로그인)
  • 도전 과제 4: 프론트엔드 JS 코드 - Fetch (회원 가입)
  • 도전 과제 5: 프론트엔드 JS 코드 - Fetch (게시글 목록 조회)
  • 도전 과제 6: HTTP REST API 수정

💭 오늘의 회고

  • Fetch는 패턴이 비슷해서 하나를 이해하고 나니 나머지 코드의 작성이 Event 보다도 수월한 것 같았다.

🔗 참고 자료 및 링크