[JS] Node.js의 ejs 템플릿 엔진과 form태그로 input 데이터 가져오고 내보내기

J.A.Y·2024년 2월 1일
0

javaScript

목록 보기
8/21
post-thumbnail

Node.js의 ejs 템플릿 엔진과 form태그를 활용해 input에 들어온 값을 불러들이고 사용하는 방법에 관한 글입니다.

이 글에서 사용하고 있는 툴 : express(node.js 웹 어플리케이션 프레임워크), ejs(템플릿 엔진)

Form

Form 태그 속성 종류

속성이 굉장히 많은데 가장 많이 사용되는 속성들을 위주로 알아보겠습니다.

  1. action: input을 통해 들어온 데이터를 제출 할 URL을 지정합니다. 지정하지 않으면 데이터는 현재 페이지의 URL로 보내집니다.

  2. method: 데이터를 제출할 때 사용하고자 하는 HTTP방법을 지정합니다. 일반적으로는 "GET"과 "POST"가 있습니다.

  3. name: Form의 이름을 지정합니다. 여러 개의 form을 제출 또는 스크립팅할 때 해당 form이 어느 form인지 식별할 때 사용합니다.

  4. target: Form을 제출한 후 응답을 표시할 위치를 지정합니다. 일반적인 값은 "_blanck", "_self", "_parent" 및 "_top"입니다.

  5. enctype: Form 데이터를 서버에 제출하기 전에 인코딩해야 합니다. enctype는 인코딩 방법을 지정합니다 . 일반적으로 "application/x-www-form-urlencoded" 등이 있습니다.

  6. autocomplete: 브라우저가 사용자의 이전 입력을 기반으로 내용을 자동으로 완성할지 말지에 대한 여부를 지정하는 것입니다.

  7. novalidate: 제출 시 Form의 유효성을 검사하지 않도록 지정합니다. Javascript를 이용해서 수동으로 유효성 검사를 하려는 경우 해당 속성을 활용하면 됩니다.

  8. accept-charset: Form 데이터를 제출할 때 사용되는 문자 인코딩을 지정합니다.

그외, accept, align, autocapitalize, spellcheck, id, class, style, titile, lang, dir, tabindex, accesskey, hidden 등 다양합니다.

input 데이터 가져오기

우선 server.js에서 최초의 index.ejs를 라우터해줍니다.

app.get("/", (req, res) => {
    res.render("index");
});

그런 뒤 index.ejs에서 보내는 폼 데이터를 받아올 사이트를 라우터해주고, method: get이라면 이때 프론트에서 요청하는 값을 req.query로 받아야 합니다.

<form method: get></from>일 때:

app.get("/getProfile", (req, res) => {
    console.log(req.query); //정상적으로 작동하는지 콘솔결과를 통해 확인
    res.render("ProfileForm", { title: "GET용 프로필", place: "Get", userInfo: req.query });
});

만약 post방식으로 받고자 한다면 req.body로 받아야 합니다.

form method: post></from>일 때:

app.post("/postProfile", (req, res) => {
      console.log(req.body);
    //post 방식으로 할 때는 req.body로 받는다.
    res.render("profileForm", { title: "POST용 프로필", place: "Post", userInfo: req.body });
});

index.ejs에서, formactionmethod, inputname을 필수로 작성해줘야합니다.

<form action="/getProfile" method="GET">
  <input type="text" placeholder="id" name="id" required />
  <input type="password" placeholder="pw" name="pw" required />
  <button type="submit">제출</button>
</form>

이제 콘솔에 정상적으로 출력되는지 확인해보면 아래 그림처럼 프론트로부터 정상적으로 값을 받아오고 있음을 확인할 수 있습니다.

EJS <%= %>를 사용해 결과값 출력하기

프론트에서 받아오는 값 말고도 백에서 데이터를 별도로 만들어 저장할 수도 있습니다.

예를 들어 getProfile이라는 주소에 title, place, 그리고 userInfo객체를 만들어보겠습니다.

app.get("/getProfile", (req, res) => {
    //get 방식일 때는 request.query로 받는다.
    console.log(req.query);
    res.render("ProfileForm", { title: "GET용 프로필", place: "Get", userInfo: req.query });
});

userInfo를 제외하고 나머지 둘은 백에서 별도로 저장한 값입니다. 이것이 ejs에서 정상적으로 출력되는지 확인해보겠습니다.

 <h3><%= title %></h3>
            <div><span><%= userInfo.id %>님 환영합니다! 자기소개를 위한 프로필을 완성해보세요.</span></div>

"GET용 프로필", 잘 출력되네요!

이러한 절차를 거쳐서 간단하게 개인 프로필을 생성해보는 사이트를 만들어 보았습니다.
결과 화면은 위에 보이는 gif입니다.


여기서부터는 사이트 구현을 위해 작성된 코드입니다.
  • server.js :
const express = require("express");
const app = express();
const PORT = 8080;
const HOST = "0.0.0.0";

/*
node.js는 순서가 중요하다. 뒤죽박죽되면 코드가 안 먹힌다.
body-parser > 미들웨어 > 주소 > app.listen해서 불러오기
*/

//body-parser
app.use(express.urlencoded({ extended: true })); //x-ww-form-urlencoded방식
app.use(express.json()); // json방식

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

//router : 서버 주소를 각각 만드는 것
app.get("/", (req, res) => {
    res.render("index");
});

app.get("/getProfile", (req, res) => {
    //get 방식일 때는 request.query로 받는다.
    console.log(req.query);
    res.render("ProfileForm", { title: "GET용 프로필", place: "Get", userInfo: req.query });
});
app.post("/postProfile", (req, res) => {
    //post 방식으로 할 때는 req.body로 받는다.
    res.render("profileForm", { title: "POST용 프로필", place: "Post", userInfo: req.body });
    console.log(req.body);
});

app.get("/resultByGet", (req, res) => {
    res.render("result", { title: "Get용 프로필 완성!", userInfo: req.query });
});
app.post("/resultByPost", (req, res) => {
    res.render("result", { title: "Post용 프로필 완성!", userInfo: req.body });
});

//서버 실행
app.listen(PORT, () => {
    console.log(`http://localhost:${PORT}`);
});
  • index.ejs :
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Login Page</title>
    </head>
    <body>
        <ul>
            <h3>로그인하고 프로필을 완성해보세요.</h3>
            <h4>로그인 방식(1):GET</h4>
            <!-- router 이름 : getFrom , 메소드명이 GET인가보다-->
            <form action="/getProfile" method="GET">
                <input type="text" placeholder="id" name="id" required />
                <input type="password" placeholder="pw" name="pw" required />
                <button type="submit">제출</button>
            </form>
        </ul>
        <hr />
        <ul>
            <h4>로그인 방식(2):POST</h4>
            <form action="/postProfile" method="POST">
                <input type="text" placeholder="id" name="id" required />
                <input type="password" placeholder="pw" name="pw" required />
                <button type="submit">제출</button>
            </form>
        </ul>
    </body>
</html>
  • profileForm.ejs:
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title><%= title %></title>
    </head>
    <body>
        <section>
            <h3><%= title %></h3>
            <div><span><%= userInfo.id %>님 환영합니다! 자기소개를 위한 프로필을 완성해보세요.</span></div>
            <br />
            <form action="/resultBy<%= place %>" method="<%= place %>">
                <div>
                    <label for="name" name="name"> 이름 </label> <input type="text" id="name" name="name" required />
                </div>
                <br />
                <fieldset>
                    <legend>성별</legend>
                    <label for="gender">남자</label
                    ><input type="radio" name="gender" id="gender" value="Male" required />
                    <label for="gender">여자</label
                    ><input type="radio" name="gender" id="gender" value="Female" required />
                </fieldset>
                <br />
                <fieldset>
                    <legend>생년월일</legend>
                    <input type="date" name="birth" id="birth" required />
                </fieldset>
                <br />
                <fieldset>
                    <legend>좋아하는 색상</legend>
                    <input type="color" name="favoriteColor" />
                </fieldset>
                <br />
                <fieldset>
                    <legend>관심사</legend>
                    <label for="hobby1">여행</label>
                    <input type="checkbox" name="hobby" id="hobby1" value="여행" />
                    <label for="hobby2">패션</label> <input type="checkbox" name="hobby" id="hobby2" value="패션" />
                    <label for="hobby3">음식</label> <input type="checkbox" name="hobby" id="hobby3" value="음식" />
                    <br />
                    <label for="hobby4">기타</label> <input type="text" name="hobby" id="hobby4" />
                </fieldset>
                <br />
                <div>
                    <button type="submit">제출</button>
                    <button type="button"><a href="/" style="text-decoration: none"> 홈 이동</a></button>
                </div>
            </form>
        </section>
    </body>
</html>
  • result.ejs:
<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title><%= userInfo.name %>님의 프로필입니다.</title>
    </head>
    <body>
        <section>
            <h3><%= title %></h3>
            <fieldset>
                <legend><span style="font-weight: bold"><%= userInfo.name %>님의 프로필</span></legend>
                <div>
                    <ul>
                        성별: <%= userInfo.gender %>
                    </ul>
                    <ul>
                        생년월일: <%= userInfo.birth %>
                    </ul>
                    <ul>
                        좋아하는 색상: <%= userInfo.favoriteColor %>
                        <br />
                        <div style="width: 140px; height: 20px; background-color: <%= userInfo.favoriteColor %>"></div>
                    </ul>
                    <ul>
                        관심사:
                        <span style="text-decoration: none"><%= userInfo.hobby.join(' / ') %></span>
                    </ul>
                </div>
            </fieldset>
            <br />
            <button type="button"><a href="/" style="text-decoration: none"> 홈으로 이동</a></button>
        </section>
    </body>
</html>
profile
Done is better than perfect🏃‍♀️

0개의 댓글