Node.js의 ejs 템플릿 엔진과 form태그를 활용해 input에 들어온 값을 불러들이고 사용하는 방법에 관한 글입니다.
이 글에서 사용하고 있는 툴 : express(node.js 웹 어플리케이션 프레임워크), ejs(템플릿 엔진)
속성이 굉장히 많은데 가장 많이 사용되는 속성들을 위주로 알아보겠습니다.
- action: input을 통해 들어온 데이터를 제출 할 URL을 지정합니다. 지정하지 않으면 데이터는 현재 페이지의 URL로 보내집니다.
- method: 데이터를 제출할 때 사용하고자 하는 HTTP방법을 지정합니다. 일반적으로는 "GET"과 "POST"가 있습니다.
- name: Form의 이름을 지정합니다. 여러 개의 form을 제출 또는 스크립팅할 때 해당 form이 어느 form인지 식별할 때 사용합니다.
- target: Form을 제출한 후 응답을 표시할 위치를 지정합니다. 일반적인 값은 "_blanck", "_self", "_parent" 및 "_top"입니다.
- enctype: Form 데이터를 서버에 제출하기 전에 인코딩해야 합니다. enctype는 인코딩 방법을 지정합니다 . 일반적으로 "application/x-www-form-urlencoded" 등이 있습니다.
- autocomplete: 브라우저가 사용자의 이전 입력을 기반으로 내용을 자동으로 완성할지 말지에 대한 여부를 지정하는 것입니다.
- novalidate: 제출 시 Form의 유효성을 검사하지 않도록 지정합니다. Javascript를 이용해서 수동으로 유효성 검사를 하려는 경우 해당 속성을 활용하면 됩니다.
- accept-charset: Form 데이터를 제출할 때 사용되는 문자 인코딩을 지정합니다.
그외, accept, align, autocapitalize, spellcheck, id, class, style, titile, lang, dir, tabindex, accesskey, hidden 등 다양합니다.
우선 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
에서, form
의 action
과 method
, input
의 name
을 필수로 작성해줘야합니다.
<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>
이제 콘솔에 정상적으로 출력되는지 확인해보면 아래 그림처럼 프론트로부터 정상적으로 값을 받아오고 있음을 확인할 수 있습니다.
프론트에서 받아오는 값 말고도 백에서 데이터를 별도로 만들어 저장할 수도 있습니다.
예를 들어 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입니다.
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}`);
});
<!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>
<!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>
<!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>