SeSAC x CodingOn 웹 취업 부트캠프

[새싹/코딩온] 풀스택 웹 개발자 취업 부트캠프 5주차 (1): 동적 폼 전송

haeriyouu 2024. 12. 12. 13:05

동적 폼 전송 (fetch, ajax, axios)

 

유저가 서버에 원하는 데이터를 GET요청을 보냄. 주소창에 URL을 넣거나 Form태그를 이용해서 버튼으로 요청을 할 수 있음. 그러나 이 두개는 브라우저가 새로고침이 된다. 이게 싫으면 비동기 HTTP통신을 사용하면 된다.

비동기 HTTP 통신이란?

  • response와 request를 비동기 식으로 다룰 수 있다! ➡️ 이를 통해 웹 페이지 전체를 다시 로드하지 않고도 필요한 데이터만 갱신할 수 있다.

 

💻Ajax

  • javascript를 이용해 클라이언트와 거버 간에 데이터를 주고 받는 비동기 HTTP통신
  • JQuery를 통해 쉽게 구현이 가능하나 반대로 말하면 JQuery를 사용해야만 간편하고 호환성이 보장된다.
// index.ejs

// ----- ajax 요청 -----
        // 보낼 데이터 객체형태로 만들기
        const data = {
          name: form.name.value, // "이름 값"
          gender: form.gender.value, // "여성", "남성"
        };

        /* ajax 사용 */
        $.ajax({
          type: "get", // 어떤 method로 보낼건지? (get, post, put, delete, etc.)
          url: "/ajax", // form의 action에 해당하는 곳
          data: data, // 서버로 넘겨줄 데이터

          // 통신이 성공했을 때
          success: function (res) {
            // 통신 이후에 일어날 일들
            console.log(res);
            resultBox.textContent = `GET /ajax 요청 완료 ${res.name}의 성별은 ${res.gender}`;
          },
          // 통신이 실패했을 때
          error: function (err) {
            console.log("err", err);
          },
        });
      }
      function ajaxPost() {
        const form = document.forms["register"];
        const data = {
          name: form.name.value,
          gender: form.gender.value,
        };
        $.ajax({
          type: "post",
          url: "/ajax",
          data: data,
          success: function (data) {
            console.log(data);
            resultBox.textContent = `POST /ajax 요청 완료 ${data.name}의 성별은 ${data.gender}`;
          },
          error: function (error) {
            console.log(error);
          },
        });
      }
// app.js

/** ajax 요청 */
// /ajax GET
app.get("/ajax", (req, res) => {
  console.log(req.query);
  res.send(req.query);
});

// /ajax POST
app.post("/ajax", (req, res) => {
  // body-parser 설정을 해야 req.body를 읽을 수 있다.
  console.log(req.body);
  res.send(req.body);
});

 

💻Axios

  • Node.js와 브라우저를 위한 Promise API를 활용
  • return이 Promise객체로 온다.
  • 별도의 모듈 설치가 필요하다.
// index.ejs

 // ----- axios 요청 보내기 -----
        // 1. then ~ catch 사용
        axios({
          method: "get",
          url: "/axios",
          params: data, // get 요청일 때는 params에 담아서 요청
        })
          .then(function (response) {
            // 통신에 성공했을 때
            console.log(response);
            console.log("--------------");
            console.log(response.data); // 서버에서 준 데이터
            // console.log(response.status);
            // console.log(response.statusText);
            // console.log(response.headers);
            // console.log(response.config);
            resultBox.textContent = `GET /axios 요청 완료 ${response.data.name}의 성별은 ${response.data.gender}입니다.`;
            resultBox.style.color = "green";
          })
          .catch(function (err) {
            // 통신에 실패했을 때
            console.error("error");
          });

        // 2. async ~ await 사용
        // 에러처리를 try ~ catch 문을 사용해서 해주는게 좋다.
        try {
          const response = await axios({
            method: "get",
            url: `/axios?name=${data.name}&gender=${data.gender}`,
          });
          console.log(response);
          const { name, gender } = response.data;
          resultBox.textContent = `${name}의 성별은 ${gender}`;
          resultBox.style.color = "green";
        } catch (err) {
          console.log(err);
        }
      }
      async function axiosPost() {
        const form = document.forms["register"];
        const data = {
          name: form.name.value,
          gender: form.gender.value,
        };
        try {
          const res = await axios({
            method: "post",
            url: "/axios",
            data: data,
          });
          console.log(res);
          console.log("실제데이터", res.data);
          const { name: 이름, gender: 성별 } = res.data;
          resultBox.textContent = `POST /axios 요청 완료 ${이름}의 성별은 ${성별}`;
        } catch (err) {
          console.error(err);
        }
      }
// app.js

/** axios 요청 */
// /axios GET
app.get("/axios", (req, res) => {
  console.log(req.query);
  res.send(req.query);
});

// /axios POST
app.post("/axios", (req, res) => {
  console.log(req.body);
  res.send(req.body);
});

💡Axios 문법

axios({
  url: 'https://www.naver.com',
  method: 'get',
  data: {
    name: "김덕구",
    age: 29
  }
})
.then(function(response) {
  console.log(response.data);
})
.catch(function(error) {
  console.log(error);
});

url: 요청을 보낼 서버 주소
method: HTTP 요청 메소드 (get, post, put, delete 등)
data: 서버로 보낼 데이터

 

💡 응답 처리

  • axios는 promise기반으로 동작하며, 응답을 .then()에서 처리한다.
  • 응답 객체(response)는 다음과 같은 속성을 포함한다.
    • data: 서버가 제공한 응답 데이터
    • status: HTTP 상태 코드
    • statusText: HTTP 상태 메세지
    • headers: 응답 헤더
    • config: 요청 시 사용된 구성 객체
  • res.send()
    • 클라이언트에게 다양한 유형의 응답을 보낼 수 있다.
      • 문자열, 객체, 배열, buffer등을 인자로 받는다.
      • Content-Type을 자동으로 설정한다. (객체나 배열의 경우 'application/json')
  • res.render()
    • express.js에서 뷰 템플릿을 렌더링하여 HTML을 생성하고 클라이언트에게로 보내는 메소드.
res.render('viewName', { data: 'value' });

첫번째 인자: 랜더링할 뷰 템플릿 이름
두번째 인자: 템플릿에 전달할 데이터 객체

⭐ axios는 클라이언트 측에서 HTTP 요청을 보내는 데 사용되고, res.send(), res.render()는 서버 측에서 클라이언트에게 응답을 보내는데 사용.

⭐res.send()는 일반적인 데이터 응답에, res.render()는 HTML 페이지 생성에 주로 사용된다.

더보기

저 app.get, app.post와 res.send, res.render이해하는게 시간이 좀 많이 걸렸다. 🥲

💻Fetch

  • javascript의 내장 라이브러리
  • fetch도 axios처럼 Promise기반!
    • 다만 상대적으로 axios에 비해 기능이 부족하다.
// index.ejs

      function fetchGet() {
        const form = document.forms["register"];
        const data = {
          name: form.name.value,
          gender: form.gender.value,
        };

        // fetch('/fetch',{
        //     method:'get',
        // })
        // fetch의 default method는 'GET'
        fetch(`/fetch?name=${data.name}&gender=${data.gender}`)
          .then((response) => {
            console.log(response);
            // 서버에서 넘어온 문자열을 뽑아내기 위해 text() 메소드 사용
            // text(): response 객체에서 텍스트 본문을 뽑아내기 위해 사용
            // return response.text();

            // json()): response 객체에서 오브젝트 본문을 뽑아내기 위해 사용
            return response.json();
          })
          .then((res) => {
            console.log(res);
            resultBox.textContent = `GET /fetch 요청 완료 ${res.name}의 성별은 ${res.gender}`;
            resultBox.style.color = "limegreen";
          })
          .catch((err) => {
            console.log("err", err);
          });
      }
      async function fetchPost() {
        const form = document.forms["register"];
        const data = {
          name: form.name.value,
          gender: form.gender.value,
        };
        try {
          const res = await fetch("/fetch", {
            method: "post",
            body: JSON.stringify(data), // JSON 형식으로 보내야 함
            headers: {
              "Content-Type": "application/json",
            },
          });
          console.log(res);

          // json(), text() -> 시간이 걸리는 작업
          const result = await res.json();
          console.log(result);
          // result = {name: '익수', gender: '여성'}
          const { name, gender } = result;
          resultBox.textContent = `POST /fetch 요청 결과 ${name}의 성별은 ${gender}`;
          resultBox.style.color = "gray";
        } catch (err) {
          console.log(err);
        }
      }
// app.js

/** fetch 요청 */
// /fetch GET
app.get("/fetch", (req, res) => {
  console.log(req.query);
  // 클라이언트에서 .text() 사용
  // res.send("응답완료");

  // 클라이언트에서 .json() 사용
  res.send(req.query); // 객체를 보낸다
});

// /fetch POST
app.post("/fetch", (req, res) => {
  console.log(req.body);
  res.send(req.body);
});

💻 Json

  • 키-값 쌍으로 구성된 데이터 구조 사용
  • 웹 어플리케이션에서 서버와 클라이언트 간의 데이터 교환에 사용된다.
{
  "name": "김덕구",
  "age": 29,
  "city": "서울시",
  "hobbies": ["놀고", "먹기"]
}

객체: 중괄호{}로 둘러싸인 키-값 쌍의 집합
배열: 대괄호[]로 둘러싸진 값의 순서 있는 목록
값: 문자열, 숫자, 불리언, null, 객체, 배열 등

💡Json 내장 객체

  • Javascript Object와 문자열을 서로 변환할 수 있도록 메서드 제공

1. JSON.parse(): JSON 문자열을 Javascript객체로 변환

2. JSON.stringify(): Javascript객체를 JSON 문자열로 변환

💡 유효성 검사: checkValidity()

	유효성 검사: checkValidity()
 		required가 있으면 기입이 되었는지 안되었는지 검사해준다.
   
        - required 속성이 없는 항목 -> 무조건 true를 반환한다.
        - required 속성이 있는 항목 ->
            - 기입을 했다면 true
            - 기입을 하지 않았다면 false
 
        console.log(form.name.checkValidity()); // input[name="text"]
        console.log(form.gender[0].checkValidity());
        
        if (!form.name.checkValidity()) {
          resultBox.innerText = "이름을 입력 해 주세요";
          //   resultBox.innerText = form.name.validationMessage;
          return;
        }
        if (!form.gender[0].checkValidity()) {
          resultBox.innerText = "성별을 입력 해 주세요";
          //   resultBox.innerText = form.gender[0].validationMessage;
          return;
        }