백앤드/Node.js

[포스코x코딩온] 웹개발자 입문 과정 5주차 | 비동기 HTTP 통신 종류 (ajax, axios, fetch)

영최 2023. 4. 1. 00:21
728x90

동적 폼 전송 예시

위와 같이 같은 페이지 내에서 form 전송하는 방법은 '비동기 HTTP 통신'을 통해서 할 수 있다.

(type=“submit”을 사용할 경우 다른 페이지로 이동하며 이때는 '동기 HTTP 통신'방법이다.)

 

1.비동기 HTTP통신이란?

 가.동기 방식: 한번에 하나만 처리, 순차적 방식 (페이지를 이동해서 서버가 데이터 처리)

 나.비동기 방식: 서버에 데이터를 보내고 응답을 기다리는 동안 다른 처리가 가능한 방식

  예를 들면 메일함 화면에서 메일을 확인하는 동시에 새로운 메일을 받을 수 있음 

  폼의 데이터를 서버와 'dynamic'(일부 내용 실시간 변경)하게 송수신할 때 즉 동적 폼 전송 시

  비동기 HTTP통신 방식을 사용함

 

2.JavaScript 비동기 HTTP통신 방법 세가지 

 

실습 화면

 가.Ajax: JQuery를 사용해야만 간편하다. Promise기반이 아니다. 

  JQuery CDN을 넣어줘야한다.

  Error,Success, Complete의 상태를 통해 실행흐름을 조절 가능하다.

<!-- danamic.ejs -->
<head>
    <!-- ajax 실습 위한 jQuery CDN -->
    <script
      src="https://code.jquery.com/jquery-3.6.4.min.js"
      integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8="
      crossorigin="anonymous"
    ></script>
</head>

<body>
    <!-- action을 주지 않는 이유는 페이지로 넘어가기때문에 (동기방식) -->
    <form name="register">
        <label for="name">이름</label>
        <input type="text" name="name" id="name" />

        <input type="radio" name="gender" value="남자" id="male" checked />
        <label for="male">남자</label>
        <input type="radio" name="gender" value="여자" id="female" />
        <label for="female">여자</label>

        <button type="button" onclick="ajaxGet();">ajax get 버튼</button>
        <button type="button" onclick="ajaxPost();">ajax post 버튼</button>
    </form>
 
    <div class="result"></div>

    <script>
      //버튼 실행 결과를 보여줄 요소 선택
      const resultBox = document.querySelector(".result");
      
      //1-1. ajax get 요청
      function ajaxGet() {
        console.log("click ajaxGet btn!!");

        //form 선택하기
        const form = document.forms["register"];

        //서버에 전송할 폼 입력값을 저장하는 객체
        const formInfo = {
          name: form.name.value,
          gender: form.gender.value,
        };
        $.ajax({
          url: "/ajax",
          type: "GET",
          data: formInfo,
          success: function (data) {
            console.log(data); //{name: 'www', gender: '여자'}
            resultBox.textContent = `GET /ajax 요청 완료! ${data.name}님은 ${data.gender}이시죠?`;
            resultBox.style.color = "blue";
          },
        });
      }
      
      //1-2. ajax post 요청
      function ajaxPost() {
        console.log("click ajaxPost btn!!");

        //form 선택하기
        const form = document.forms["register"];

        //서버에 전송할 폼 입력값을 저장하는 객체
        const formInfo = {
          name: form.name.value,
          gender: form.gender.value,
        };

        //ajax Post 요청 보내기
        $.ajax({
          url: "/ajax",
          type: "POST",
          data: formInfo,
          success: function (data) {
            console.log(data);
            resultBox.textContent = `POST /ajax 요청 완료! ${data.name}님은 ${data.gender}이시죠?`;
            resultBox.style.color = "red";
          },
        });
      }
    </script>    
</body>
//app.js
//1-1. /ajax get 요청
app.get("/ajax", (req, res) => {
  console.log(req.query);
  res.send(req.query);
});

//1-2. /ajax post 요청
app.post("/ajax", (req, res) => {
  console.log(req.body);
  res.send(req.body);
});

 나.Axios: Node.js를 위한 Promise API를 활용하는 라이브러리이다.

  그래서 Promise사용이 가능하다. 브라우저 호환성이 좋다.

  그러나 모듈 설치 혹은 호출이 필요하다.

  앞으로 이 방법을 가장 자주 쓰게 될 것 같다.

<!-- danamic.ejs -->
<head>
    <!-- axios 실습 위한 axios CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
    <!-- action을 주지 않는 이유는 페이지로 넘어가기때문에 (동기방식) -->
    <form name="register">
        <label for="name">이름</label>
        <input type="text" name="name" id="name" />

        <input type="radio" name="gender" value="남자" id="male" checked />
        <label for="male">남자</label>
        <input type="radio" name="gender" value="여자" id="female" />
        <label for="female">여자</label>

        <button type="button" onclick="axiosGet();">axios get 버튼</button>
        <button type="button" onclick="axiosPost();">axios post 버튼</button>
    </form>
 
    <div class="result"></div>

    <script>
      //버튼 실행 결과를 보여줄 요소 선택
      const resultBox = document.querySelector(".result");
      
      //2-1. axios get 요청
      async function axiosGet() {
        console.log("click axiosGet btn!!");
        
        //form 선택하기
        const form = document.forms["register"];

        //서버에 전송할 폼 입력값을 저장하는 객체
        const formInfo = {
          name: form.name.value,
          gender: form.gender.value,
        };
        
        //2-1-1. promise axios get 요청
        //axios는 결과로 promise 리턴
        //.then() 사용 가능
             axios({
               url: "/axios",
               method: "GET",
               params: formInfo, //GET 요청은 params에 저장, 데이터가 params로 변경됨
             })
               .then((response) => {          
                 console.log(response.data);
                 resultBox.textContent = `GET /axios 요청 완료! ${response.data.name}님은 ${response.data.gender}이시죠?`;
                 resultBox.style.color = "green";
               })
               .catch((error) => {
                 console.log("Error!", error);
               });

        //2-1-2. async await axios get 요청
        try {
          const response = await axios({
            url: "/axios",
            method: "GET",
            params: formInfo, //GET 요청은 params에 저장, 데이터가 params로 변경됨
          });
          console.log(response);
          resultBox.textContent = `GET /axios 요청 완료! ${response.data.name}님은 ${response.data.gender}이시죠?`;
          resultBox.style.color = "green";
        } catch (error) {
          console.log("Error!", error);
        }
      }
      //2-2. axios post 요청
      async function axiosPost() {
        console.log("click axiosPost btn!!");
        console.log("click axiosGet btn!!");
        
        //form 선택하기
        const form = document.forms["register"];

        //서버에 전송할 폼 입력값을 저장하는 객체
        const formInfo = {
          name: form.name.value,
          gender: form.gender.value,
        };
        axios({
          url: "/axios",
          method: "POST",
          data: formInfo, //axios POST요청은 data 키값에 담아야함(<-> GET은 params)
        })
          .then((response) => {
            console.log(response);
            resultBox.textContent = `POST /axios 요청 완료! ${response.data.name}님은 ${response.data.gender}이시죠?`;
            resultBox.style.color = "gold";
          })
          .catch((error) => {
            console.log("Error!", error.message);
            resultBox.textContent = "알 수 없는 에러 발생";
          });
      }
    </script>    
</body>
//app.js
// 2-1. /axios get 요청
app.get("/axios", (req, res) => {
  console.log(req.query);
  res.send(req.query);
});

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

 다.Fetch: ES6부터 들어온 JavaScript 내장 라이브러리로 별도 설치나 호출이 필요 없다.

  Promise 사용이 가능하다. 그러나 최신 문법이라서 axios보다 기능이 부족하다.

<!-- danamic.ejs -->

<body>
    <!-- action을 주지 않는 이유는 페이지로 넘어가기때문에 (동기방식) -->
    <form name="register">
        <label for="name">이름</label>
        <input type="text" name="name" id="name" />

        <input type="radio" name="gender" value="남자" id="male" checked />
        <label for="male">남자</label>
        <input type="radio" name="gender" value="여자" id="female" />
        <label for="female">여자</label>

        <button type="button" onclick="fetchGet();">fetch get 버튼</button>
        <button type="button" onclick="fetchPost();">fetch post 버튼</button>
    </form>
 
    <div class="result"></div>

    <script>
      //버튼 실행 결과를 보여줄 요소 선택
      const resultBox = document.querySelector(".result");
      
      //3-1. fetch get 요청
      function fetchGet() {
        console.log("click fetchGet btn!!");
        const form = document.forms["register"];
        const ulrQuery = `?name=${form.name.value}&gender=${form.gender.value}`;
        //fetch(url,options)
        //ulrQuery가 data를 대신함
        fetch(`/fetch${ulrQuery}`, {
          method: "GET",
        })
          .then((response) => {
            console.log(response);
            //json 형식으로 도착하는 응답 ->js object로 파싱
            return response.json();
          }) // axios 보다 한단계 더 해야함
          .then((data) => {
            console.log("data>>>>", data); //{ name: 's', gender: '남자' }
            resultBox.textContent = `GET /fetch 요청 완료!! ${data.name}님은 ${data.gender}이시죠?`;
            resultBox.style.color = "limegreen";
          });
      }

      function fetchPost() {
        console.log("click fetchPost btn!!");

        const form = document.forms["register"];
        const formInfo = {
          name: form.name.value,
          gender: form.gender.value,
        };

        // fetch(url, options)
        fetch("/fetch", {
          method: "POST",
          // => POST 전송시에는 headers 옵션을 통해서 JSON 포맷을 사용함을 알려줘야 함.
          headers: {
            "Content-Type": "application/json",
          },
          // formInfo: 폼 요소에 입력된 값 정보
          // => JSON.stringify() : js object -> json
          body: JSON.stringify(formInfo),
        })
          .then(function (response) {
            console.log(response);
            // json 형식으로 도착하는 응답 -> js object로 파싱
            return response.json();
          })
          .then(function (data) {
            console.log(data); // { name: 'aa', gender: '여자' }
            resultBox.textContent = `POST /fetch 요청 완료!! 
          ${data.name}님은 ${data.gender}이시죠?ㅎㅎ`;
            resultBox.style.color = "hotpink";
          });
      }
    </script>    
</body>
//app.js
//3-1. /fetch get 요청
app.get("/fetch", (req, res) => {
  console.log(req.query);
  res.send(req.query);
});

// //3-2. /fetch post 요청
app.post("/fetch", (req, res) => {
  console.log(req.body);
  res.send(req.body);
});

3.JSON이란?

 JavaScript Object Notation의 축약어로 JavaScript의 객체와 유사하지만

 키값이 "key" 큰따옴표로 묶여 있다는 차이점이 있다.

 문자열, 숫자, 불리언, 중첩된 객체와 배열 저장이 가능하다.

 client와 server간의 데이터를 주고 받는 형식이다.

 

728x90