[23] form 전송, Ajax, Axios, Fetch 방법

minjeong·2024년 2월 4일
0

1. form 전송

  • <input type = "submit">이나 <button type = "submit">을 이용해 전송
  • 전송 시 페이지 이동이 일어난다.

📌 동기 방식

  • 한번에 하나만 처리! => 페이지를 아예 이동해 서버가 데이터 처리
    📌 비동기 방식
  • 서버에 데이터를 보내고 응답을 기다리는 동안 다른 처리 가능

예제코드

(1) <button type = "submit"> 경우

 <form onsubmit="submitFunc(event)" name="button-form">
            <label for="name">이름</label>
            <input type="text" id="name" required /><br />
            <label for="email">이메일</label>
            <input type="email" id="email" required /><br />
            <!-- button에 onclick을 쓰는게 아니라면 type이 submit이어야함 -->
            <button type="submit">제출</button>
        </form>
        <script>
            function submitFunc(event) {
                event.preventDefault(); //기본 제출 동작을 막아줌
                // console.log(event);
                const form = document.forms['button-form'];
                console.log(form.name);
                console.log(form.email);
                console.log(form.name.value); //값이 보임
                console.log(form.email.value);
                console.log(document.getElementById('name').value); //name의 값을 하나만 가지고 오고 싶으면 이 문장만 써도 됌
            }
        </script>
const express = require('express');
const app = express();
const PORT = 8000;

//body-parser
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

//view engine
app.set('view engine', 'ejs');
app.set('views', './views');

//===router (실제 페이지 생성)
app.get('/', (req, res) => {
    res.render('index'); //page
});

app.get('/submit', (req, res) => {
    res.render('submit');
});

app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

(2) onclick 이용

예제코드

 <form name="button-form">
            <label for="name">이름</label>
            <input type="text" id="name" required /><br />
            <label for="email">이메일</label>
            <input type="email" id="email" required /><br />
            <button type="button" onclick="func()">제출</button>
        </form>
        <script>
            function func() {
                const form = document.forms['button-form'];
                // console.log(form);
                console.log(form.name);
                console.log(form.email);
                console.log(form.name.value); //값이 보임
                console.log(form.email.value);
                console.log(document.getElementById('name').value); //name의 값을 하나만 가지고 오고 싶으면 이 문장만 써도 됌
            }
        </script>
const express = require('express');
const app = express();
const PORT = 8000;

//body-parser
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

//view engine
app.set('view engine', 'ejs');
app.set('views', './views');

//===router (실제 페이지 생성)
app.get('/', (req, res) => {
    res.render('index'); //page
});
app.get('/func', (req, res) => {
    res.render('func');
});
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});

실행 결과

2. 비동기 HTTP 통신

  • 폼의 데이터를 서버와 dynamic하게 송수신 하는 것
    📚 dynamic : 웹 문서가 정적으로 멈춰있는 것이 아니라 일부 내용이 실시간으로 변경되는 것

(1) Ajax

  • 자바 스크립트를 이용해 클라이언트와 서버 간에 데이터를 주고 받는 비동기 HTTP 통신
  • jQuery를 통해서 구현 가능하다.
  • ejs or html에서 사용된다.(프론트엔드)
    - success 밑에는 백엔드에서 받은 값, success 위에는 백엔드로 보내는 값

예제코드

 <script>
            const resultBox = document.querySelector('.result');
            function ajaxGet() {
                //form 가져오기
                const form = document.forms['register-form'];
                //백엔드로 보내는 데이터
                const data = {
                    //객체에 담는 key값이 백엔드로 간다.
                    //json
                    name: form.name.value,
                    email: form.email.value,
                };
                //ajax
                //jquery기반
                $.ajax({
                    //백엔드로 요청하는 것
                    type: 'get',
                    url: '/ajax',
                    data: data,
                    //백엔드로 받는 것(응답)
                    success: (res) => {
                        console.log('res:', res);
                        resultBox.textContent = `${res.name} ${res.email}`; //프론트 페이지에 보여짐, 응답 받음
                    },
                });
            }
            function ajaxPost() {
                const form = document.forms['register-form'];
                if (form.name.value === '') {
                    alert('이름을 입력하세요.');
                    return; //이렇게 해야 여기서 끝나버림
                }
                if (form.email.value === '') {
                    alert('이메일을 입력하세요');
                    return;
                }
                $.ajax({
                    type: 'post',
                    url: '/ajax',
                    data: {
                        name: form.name.value,
                        email: form.email.value,
                    },
                    success: (res) => {
                        console.log('res:', res);
                        resultBox.textContent = `${res.username} ${res.email}`;
                    },
                });
            }
</script>
//router생성 및 세팅 , 서버 시작 등 공통적으로 들어가야하는 부분은 이 부분에선 제외.(1번의 예제에서 확인)
app.get('/ajax', (req, res) => {
    console.log('요청 값', req.query); //터미널에서 확인가능
    const { name, email } = req.query; //req : 요청
    //응답
    //비동기에서는 보내는건 render가 아니라 send, 응답도 객체형태로 보내면 됌
    //백엔드 설계할때 result:true 로 하면 나중에 프론트개발자가 예외처리하기 수월함
    //해당 페이지에서 처리하는 것이고, 그 다음에 다른 페이지로 이동
    res.send({ result: true, name: `${name}`, email: ` 이메일은 ${email}입니다.` }); //프론트로 보내는 데이터
});

app.post('/ajax', (req, res) => {
    console.log('요청값', req.body);
    const { name, email } = req.body;
    res.send({ result: true, username: name, email }); //{username:name , email:email} 이라는 의미 , 이름 같은건 생략가능
});

(2) Axios

  • 세개의 통신방법 중에 가장! 중요하다.
  • Node.js와 브라우저를 위한 Promise API를 활용
  • 프론트, 백엔드에서 모두 사용 가능
  • 비동기 HTTP 통신이 가능하고, return이 Promise 객체로 온다.
  • 백엔드에서 Axios를 쓰는 것은 백엔드에서 백엔드로 전송할 때 쓰인다.
    -> Get 요청일때는 params를 이용해서 전송하고, Post 요청은 data를 이용해서 전송한다.
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

html의 head위치에 붙여넣기 해줘야 axios가 작동한다.
-axios cdn-

예제코드

<script>
function axiosGet() {
                const form = document.forms['register-form'];
                const data = {
                    username: form.name.value,
                    mail: form.email.value,
                };
                //axios
                axios({
                    method: 'get', //통신하고자 하는 방식
                    url: '/axios', // 통신하고자 하는 주소, form에서의 action에 해당, 보내고자 하는 주소!!!
                    params: data, 
                }).then((res) => {
                    console.log('res', res);
                    // resultBox.textContent = `${res.username}님 주소는 ${res.mail}입니다.`; //이렇게만 하면 모든 데이터가 다 보여지게 되서 undefined가 됨
                    resultBox.textContent = `${res.data.username}님 주소는 ${res.data.mail}입니다.`;
                });
            }
  
async function axiosPost() {
                const data = {
                    username: document.querySelector('#name').value,
                    email: document.querySelector('#email').value,
                };
                const res = await axios({
                    method: 'post',
                    url: '/axios',
                    data,
                });
                console.log('res', res);
                const { name, address } = res.data;
                resultBox.textContent = name + address;
               
            }
</script>
//axios
app.get('/axios', (req, res) => {
    console.log('요청값', req.query); //req.query 자체가 json형태여서 중괄호로 되어있어서 그냥 보내줘도 됌
    res.send(req.query); //요청한거 그대로 보냄
});

app.post('/axios', (req, res) => {
    console.log('요청값', req.body);
    const { username, email } = req.body;
    const data = {
        name: `안녕하세요 ${username}`,
        address: `주소는 ${email}입니다`,
    };
    res.send(data);
});

✅ 참고

<script>
axios({
  url : '통신하고자 하는 주소',
  method : 'get'
</script>

➡️ Params 값을 안 보낼거면 url 자체를 http://~~~?key=value&key=value라고 보내도 가능

(3) Fetch

  • ES6부터 들어온 Javascript 내장 라이브러리이므로 별도의 import가 필요없다.
  • Promise 기반
  • Timeout 기능이 없다.

예제코드

<script>
function fetchGet() {
                const form = document.forms['register-form'];
                //querystring을 만들어줘야함
                const url = `?name=${form.name.value}&email=${form.email.value}`;

                fetch(`/fetch${url}`, {
                    method: 'get',
                })
                    .then((res) => {
                        console.log('res', res);
                        //json응답을 네이티브 javascript 객체로 파싱
                        return res.json();
                    })
                    .then((data) => {
                        console.log('data', data);
                        resultBox.textContent = `${data.name}님 주소는 ${data.email}입니다`;
                    });
            }
            function fetchPost() {
                const data = {
                    username: document.querySelector('#name').value,
                    email: document.querySelector('#email').value,
                };
                fetch('/fetch', {
                    method: 'post',
                    body: JSON.stringify(data), //객체를 문자열 형태로 보냄, 그냥 보내면 오류 발생, js가서는 알아서 처리됌
                    headers: {
                        //전송타입
                        'Content-Type': 'application/json',
                    },
                })
                    .then((res) => {
                        console.log('res', res);
                        return res.json();
                    })
                    .then((data) => {
                        console.log('data', data);
                        resultBox.textContent = `${data.name}님 주소는 ${data.email}입니다`;
                    });
            }
        </script>
//fetch
//querystring은 데이터 이기때문에 index.js에서 url 전부를 써주지 않아도 됌
app.get('/fetch', (req, res) => {
    console.log('요청값', req.query);
    res.send(req.query);
});

app.post('/fetch', (req, res) => {
    console.log('요청값', req.body);
    res.send(req.body);
});

예제 코드(공통 html 부분)

<form name="register-form">
            <label for="name">이름</label>
            <!-- 비동기일땐 required을 html에 하면 안되서 js로해야함 -->
            <input type="text" id="name" required /><br />
            <label for="email">이메일</label>
            <input type="email" id="email" required /><br /><br />
            <button type="button" onclick="ajaxGet()">ajax get 제출</button>
            <button type="button" onclick="ajaxPost()">ajax post 제출</button>
            <button type="button" onclick="axiosGet()">axios get 제출</button>
            <button type="button" onclick="axiosPost()">axios post 제출</button>
            <button type="button" onclick="fetchGet()">fetch get 제출</button>
            <button type="button" onclick="fetchPost()">fetch post 제출</button>
        </form>
        <div class="result"></div>

참고

✅ 페이지 응답 및 요청에서 사용되는 함수

  • render() : 뷰페이지 렌더링 render(뷰페이지이름, 데이터(선택사항))
  • send() : 모든 타입 데이터 전송(즉, 문자열, 배열, 객체, 숫자, 불린값 등..)
  • json(): 객체 타입 데이터 전송
  • redirect() : 페이지 강제 이동, redirect(페이지명)

    마무리

    여러 통신 방법들의 예제를 여러번 확인하면서 차이점이나 어디에서 이용해야하는지 숙지해야할 것 같다..!
profile
중요한 건 꺾여도 다시 일어서는 마음

0개의 댓글