1) Node.js
1-1) HTTP
1-2) 동적 웹 페이지 구현
1) Node.js
1-1) HTTP
HTTP는 한 번 request와 response를 주고 받으면 연결을 끊기 때문에
다시 request와 response를 주고 받으려면 반드시 다시 연결(3-way Handshaking)을 먼저 한 뒤
request와 response를 주고 받아야 한다!!(HTTP의 "비연결성")
request와 response가 파일 단위로 계속 주고 받는다는 점을 명심할 것!!
- lib
- req.js
- res.js
- template.js
- views
- html 파일들...(index.html, list.html, write.html, modify.html, view.html)
- server.js
코드 작업 순서
1. server 실행 부분부터 먼저 만듦!
2. 이후 응답주는 코드를 만듦!(여기서 응답에는 "send"와 "sendFile"이 있다!)
- send
- sendFile
3. 서버 측에서 요청 데이터를 받는 것을 만듦!
server.js
const net = require("net");
const resFn = require("./lib/res");
const reqFn = require("./lib/req");
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || "127.0.0.1";
const server = net.createServer((client) => {
client.setEncoding("utf8");
client.on("data", (chunk) => {
// 여기서 req, res가 잘 찍히는지 확인해야 함!!
const res = resFn(client);
const req = reqFn(chunk); // string을 줘서 이를 object로 반환하도록 함!!
if (req.method === "GET" && req.path === "/") {
res.sendFile("index.html");
} else if (req.method === "GET" && req.path === "/list") {
res.sendFile("list.html");
} else if (req.method === "GET" && req.path === "/view") {
res.sendFile("view.html");
} else if (req.method === "GET" && req.path === "/write") {
res.sendFile("write.html");
} else if (req.method === "GET" && req.path === "/modify") {
res.sendFile("modify.html");
}
});
});
server.on("connection", () => {
console.log("connected to client");
});
server.listen(PORT, HOST, () => {
console.log("server start");
});
req.js
const msg = `GET /user?name=sangbeom&age=27 HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Content-Type: application/json
{
"name":"sangbeom",
"age":27
}`;
const getQuery = (queryString) => {
if (queryString === undefined) return null;
return queryString
.split("&")
.map((v) => v.split("="))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
};
const bodyParser = (body, contentType) => {
if (contentType === undefined) return null;
if (contentType.indexOf("application/json") !== -1) return JSON.parse(body);
if (contentType.indexOf("application/x-www-form-urlencoded") !== -1)
return getQuery(body);
return body;
};
const getMessage = (message) => {
let flag = false;
let body = "";
for (const key in message) {
if (flag)
body = message
.splice(key)
.map((v) => v.trim())
.join("");
if (message[key] === "") flag = true;
}
message.pop();
const headers = message
.map((v) => v.split(":"))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
body = bodyParser(body, headers["Content-Type"]);
return [headers, body];
};
const parser = (message) => {
const header = message.split("\r\n");
const [method, url, version] = header.shift().split(" ");
const [path, queryString] = url.split("?");
const query = getQuery(queryString);
// header와 body 분리하기
const [headers, body] = getMessage(header);
return { method, url, version, path, queryString, query, headers, body };
};
// 결과 확인용 코드
// const result = parser(msg);
// console.log(result);
module.exports = parser;
res.js
const readFile = require("./template"); // 결과값이 "function"이다!!
const message = (content) => {
const body = Buffer.from(content);
return `HTTP/1.1 200 OK
Connection:Close
Content-Type:text/html; charset=UTF-8
Content-Length:${body.length}
${body.toString()}`;
};
module.exports = (socket) => {
return {
send: (body) => {
const response = message(body);
socket.write(response);
},
sendFile: (filename) => {
const body = readFile(filename);
const response = message(body);
socket.write(response);
},
};
};
template.js
const fs = require("fs");
const path = require("path");
module.exports = (filename, obj = {}, defaultDir = "../views") => {
const target = path.join(__dirname, defaultDir, filename);
const readline = fs.readFileSync(target, "utf8");
return readline;
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
index 페이지 입니다.
</body>
</html>
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
list 페이지 입니다.
</body>
</html>
write.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
write 페이지 입니다.
</body>
</html>
view.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
view 페이지 입니다.
</body>
</html>
modify.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
modify 페이지 입니다.
</body>
</html>
1-2) 동적 웹 페이지 구현
server.js
const net = require("net");
const resFn = require("./lib/res");
const reqFn = require("./lib/req");
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || "127.0.0.1";
const server = net.createServer((client) => {
client.setEncoding("utf8");
client.on("data", (chunk) => {
// 여기서 req, res가 잘 찍히는지 확인해야 함!!
const req = reqFn(chunk); // string을 줘서 이를 object로 반환하도록 함!!
const res = resFn(client, req);
if (req.method === "GET" && req.path === "/") {
// const { name } = req.query; // name 속성의 값이 없는 경우, 즉 "undefined"일 때 코드 에러가 나서 서버가 꺼진다는 문제가 있음!!
const name = req.query?.name; // 위의 문제를 해결하기 위해 name 속성의 값이 없으면 "undefined"를 그대로 반환하게 하는 신문법 코드이다!!
res.sendFile("index.html", { name, title: "메인 페이지입니다." });
} else if (req.method === "GET" && req.path === "/list") {
res.sendFile("list.html");
} else if (req.method === "GET" && req.path === "/view") {
res.sendFile("view.html");
} else if (req.method === "GET" && req.path === "/write") {
res.sendFile("write.html");
} else if (req.method === "GET" && req.path === "/modify") {
res.sendFile("modify.html");
}
});
});
server.on("connection", () => {
console.log("connected to client");
});
server.listen(PORT, HOST, () => {
console.log("server start");
});
req.js
const msg = `GET /user?name=sangbeom&age=27 HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Content-Type: application/json
{
"name":"sangbeom",
"age":27
}`;
const getQuery = (queryString) => {
if (queryString === undefined) return null;
return queryString
.split("&")
.map((v) => v.split("="))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
};
const bodyParser = (body, contentType) => {
if (contentType === undefined) return null;
if (contentType.indexOf("application/json") !== -1) return JSON.parse(body);
if (contentType.indexOf("application/x-www-form-urlencoded") !== -1)
return getQuery(body);
return body;
};
const getMessage = (message) => {
let flag = false;
let body = "";
for (const key in message) {
if (flag)
body = message
.splice(key)
.map((v) => v.trim())
.join("");
if (message[key] === "") flag = true;
}
message.pop();
const headers = message
.map((v) => v.split(":"))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
body = bodyParser(body, headers["Content-Type"]);
return [headers, body];
};
const parser = (message) => {
const header = message.split("\r\n");
const [method, url, version] = header.shift().split(" ");
const [path, queryString] = url.split("?");
const query = getQuery(queryString);
const [headers, body] = getMessage(header);
return { method, url, version, path, queryString, query, headers, body };
};
// 결과 확인용 코드
// const result = parser(msg);
// console.log(result);
module.exports = parser;
res.js
const readFile = require("./template"); // 결과값이 "function"이다!!
const message = (content) => {
const body = Buffer.from(content);
return `HTTP/1.1 200 OK
Connection:Close
Content-Type:text/html; charset=UTF-8
Content-Length:${body.length}
${body.toString()}`;
};
module.exports = (socket, req) => {
return {
send: (body) => {
const response = message(body);
socket.write(response);
},
sendFile: (filename, obj = {}) => {
const body = readFile(filename, obj); //
const response = message(body);
socket.write(response);
},
};
};
template.js
const fs = require("fs");
const path = require("path");
// {name:'sangbeom'}
module.exports = (filename, obj = {}, defaultDir = "../views") => {
// obj = {name:'sangbeom', title:"메인 페이지 입니다."}
console.log(obj);
const target = path.join(__dirname, defaultDir, filename);
let readline = fs.readFileSync(target, "utf8"); // html string에 해당함!!
// Javascript 스펙
// String.prototype.replaceAll(찾을 단어, 바꿀 단어)
// let text = readline.replaceAll("{{name}}", obj.name);
// text = text.replaceAll("{{title}}", obj.title);
for (const key in obj) {
// key = name, obj[key] = 'sangbeom'
readline = readline.replaceAll(`{{${key}}}`, obj[key]);
// console.log(key, obj[key]); // 확인용 코드
}
return readline;
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{title}}</title>
</head>
<body>
index 페이지 입니다. {{name}}
</body>
</html>
CSS, Javascript 적용 버전 코드
server.js
const net = require("net");
const resFn = require("./lib/res");
const reqFn = require("./lib/req");
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || "127.0.0.1";
const server = net.createServer((client) => {
client.setEncoding("utf8");
client.on("data", (chunk) => {
// 여기서 req, res가 잘 찍히는지 확인해야 함!!
const req = reqFn(chunk); // string을 줘서 이를 object로 반환하도록 함!!
const res = resFn(client, req);
if (req.method === "GET" && req.path === "/") {
// const { name } = req.query;
const name = req.query?.name;
res.sendFile("index.html", { name:name, title: "메인 페이지입니다." });
} else if (req.method === "GET" && req.path === "/list") {
res.sendFile("list.html");
} else if (req.method === "GET" && req.path === "/view") {
res.sendFile("view.html");
} else if (req.method === "GET" && req.path === "/write") {
res.sendFile("write.html");
} else if (req.method === "GET" && req.path === "/modify") {
res.sendFile("modify.html");
} else if (req.method === "GET" && req.path === "/css/index.css") {
res.sendStatic("/css/index.css");
} else if (req.method === "GET" && req.path === "/js/index.js") {
res.sendStatic("/js/index.js");
}
});
});
server.on("connection", () => {
console.log("connected to client");
});
server.listen(PORT, HOST, () => {
console.log("server start");
});
req.js
const msg = `GET /user?name=sangbeom&age=27 HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Content-Type: application/json
{
"name":"sangbeom",
"age":27
}`;
const getQuery = (queryString) => {
if (queryString === undefined) return null;
return queryString
.split("&")
.map((v) => v.split("="))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
};
const bodyParser = (body, contentType) => {
if (contentType === undefined) return null;
if (contentType.indexOf("application/json") !== -1) return JSON.parse(body);
if (contentType.indexOf("application/x-www-form-urlencoded") !== -1)
return getQuery(body);
return body;
};
const getMessage = (message) => {
let flag = false;
let body = "";
for (const key in message) {
if (flag)
body = message
.splice(key)
.map((v) => v.trim())
.join("");
if (message[key] === "") flag = true;
}
message.pop();
const headers = message
.map((v) => v.split(":"))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
body = bodyParser(body, headers["Content-Type"]);
return [headers, body];
};
const parser = (message) => {
const header = message.split("\r\n");
const [method, url, version] = header.shift().split(" ");
const [path, queryString] = url.split("?");
const query = getQuery(queryString);
const [headers, body] = getMessage(header);
return { method, url, version, path, queryString, query, headers, body };
};
// 결과 확인용 코드
// const result = parser(msg);
// console.log(result);
module.exports = parser;
res.js
const readFile = require("./template"); // 결과값이 "function"이다!!
const message = (content, req) => {
const body = Buffer.from(content);
let contentType = "";
if (req.headers.Accept.indexOf("text/html") !== -1) {
contentType = "text/html";
} else {
contentType = req.headers.Accept;
}
return `HTTP/1.1 200 OK
Connection:Close
Content-Type:${contentType}; charset=UTF-8
Content-Length:${body.length}
${body.toString()}`;
};
module.exports = (socket, req) => {
return {
send: (body) => {
const response = message(body, req);
socket.write(response);
},
sendFile: (filename, obj = {}) => {
const body = readFile(filename, obj); //
const response = message(body, req);
socket.write(response);
},
sendStatic: (filename) => {
const defaultDir = "../public";
const body = readFile(filename, {}, defaultDir);
const response = message(body, req);
socket.write(response);
},
};
};
template.js
const fs = require("fs");
const path = require("path");
// {name:'sangbeom'}
module.exports = (filename, obj = {}, defaultDir = "../views") => {
// obj = {name:'sangbeom', title:"메인 페이지 입니다."}
console.log(obj);
const target = path.join(__dirname, defaultDir, filename);
let readline = fs.readFileSync(target, "utf8"); // html string에 해당함!!
// Javascript 스펙
// String.prototype.replaceAll(찾을 단어, 바꿀 단어)
// let text = readline.replaceAll("{{name}}", obj.name);
// text = text.replaceAll("{{title}}", obj.title);
for (const key in obj) {
// key = name, obj[key] = 'sangbeom'
readline = readline.replaceAll(`{{${key}}}`, obj[key]);
// console.log(key, obj[key]); // 확인용 코드
}
return readline;
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="/css/index.css" />
<script type="text/javascript" src="/js/index.js"></script>
</head>
<body>
index 페이지 입니다. {{name}}
</body>
</html>
index.css
* {
margin: 0;
padding: 0;
}
body {
background: #bee;
}
index.js
alert("success?");
CSS, Javascript 적용 버전 코드 - Refactoring
test.js
// fs(파일 시스템)
// fs.readdir => 비동기로 처리됨!
// fs.readdirSync => 동기적으로 처리되며, 이는 "ls"와 같다!!(파일명을 배열로 return해 줌!!)
const fs = require("fs");
const path = require("path");
// 경로
const searchPath = path.join(__dirname, "public");
const dir = fs.readdirSync(searchPath);
console.log(dir); // [ 'css', 'images', 'js' ]
// fs.stat(경로) : 해당 경로에 있는 directory 또는 file의 정보를 나타내줌!(비동기)
// fs.statSync(경로) : 해당 경로에 있는 directory 또는 file의 정보를 나타내줌!(동기)
// fs.stat(경로)과 fs.statSync(경로)의 경우, return 값이 객체이며, 해당 객체 안에는 method들이 많다!
// 이 method들 중에 isFile() 메서드가 있는데 이를 통해 파일인지 아닌지 알 수 있음!!
for (const index in dir) {
console.log(dir[index]);
}
const find = path.join(searchPath, "1.js");
// const fileStat = fs.statSync(find); // return 값이 객체(Object)이다!!
// console.log(fileStat.isFile()); // return 값이 boolean이다!!
const isFile = fs.statSync(find).isFile();
console.log(isFile); // return 값이 boolean이다!!
/*
// 아래 내용을 구현하려 함!!
{
'/css/index.css':'index.css',
'/css/header/index.css':'index.css',
'/images/1.jpg':'1.jpg',
'/js/index.js':'index.js',
'/1.js':'1.js'
}
*/
// 해당 내용이 디렉토리일 경우,
// 해당 내용이 파일일 경우
server.js
const net = require("net");
const resFn = require("./lib/res");
const reqFn = require("./lib/req");
const static = require("./lib/static");
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || "127.0.0.1";
const server = net.createServer((client) => {
client.setEncoding("utf8");
client.on("data", (chunk) => {
// 여기서 req, res가 잘 찍히는지 확인해야 함!!
const req = reqFn(chunk); // string을 줘서 이를 object로 반환하도록 함!!
const res = resFn(client, req);
for (const path in static) {
if (req.method === "GET" && req.path === path) {
res.sendStatic(path);
}
}
if (req.method === "GET" && req.path === "/") {
// const { name } = req.query;
const name = req.query?.name;
res.sendFile("index.html", { name, title: "메인 페이지입니다." });
} else if (req.method === "GET" && req.path === "/list") {
res.sendFile("list.html");
} else if (req.method === "GET" && req.path === "/view") {
res.sendFile("view.html");
} else if (req.method === "GET" && req.path === "/write") {
res.sendFile("write.html");
} else if (req.method === "GET" && req.path === "/modify") {
res.sendFile("modify.html");
} else if (req.method === "POST" && req.path === "/write") {
console.log(req.body.subject);
}
});
});
server.on("connection", () => {
console.log("connected to client");
});
server.listen(PORT, HOST, () => {
console.log("server start");
});
req.js
const msg = `GET /user?name=sangbeom&age=27 HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Not?A_Brand";v="8", "Chromium";v="108", "Google Chrome";v="108"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Content-Type: application/json
{
"name":"sangbeom",
"age":27
}`;
const getQuery = (queryString) => {
if (queryString === undefined) return null;
return queryString
.split("&")
.map((v) => v.split("="))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
};
const bodyParser = (body, contentType) => {
if (contentType === undefined) return null;
if (contentType.indexOf("application/json") !== -1) return JSON.parse(body);
if (contentType.indexOf("application/x-www-form-urlencoded") !== -1)
return getQuery(body);
return body;
};
const getMessage = (message) => {
let flag = false;
let body = "";
for (const key in message) {
if (flag)
body = message
.splice(key)
.map((v) => v.trim())
.join("");
if (message[key] === "") flag = true;
}
message.pop();
const headers = message
.map((v) => v.split(":"))
.reduce((acc, value) => {
const [key, val] = value;
acc[key] = val;
return acc;
}, {});
body = bodyParser(body, headers["Content-Type"]);
return [headers, body];
};
const parser = (message) => {
const header = message.split("\r\n");
const [method, url, version] = header.shift().split(" ");
const [path, queryString] = url.split("?");
const query = getQuery(queryString);
const [headers, body] = getMessage(header);
return { method, url, version, path, queryString, query, headers, body };
};
// 결과 확인용 코드
// const result = parser(msg);
// console.log(result);
module.exports = parser;
res.js
const readFile = require("./template"); // 결과값이 "function"이다!!
const message = (content, req) => {
const body = Buffer.from(content);
let contentType = "";
if (req.headers.Accept.indexOf("text/html") !== -1) {
contentType = "text/html";
} else {
contentType = req.headers.Accept;
}
return `HTTP/1.1 200 OK
Connection:Close
Content-Type:${contentType}; charset=UTF-8
Content-Length:${body.length}
${body.toString()}`;
};
module.exports = (socket, req) => {
return {
send: (body) => {
const response = message(body, req);
socket.write(response);
},
sendFile: (filename, obj = {}) => {
const body = readFile(filename, obj); //
const response = message(body, req);
socket.write(response);
},
sendStatic: (filename) => {
const defaultDir = "../public";
const body = readFile(filename, {}, defaultDir);
const response = message(body, req);
socket.write(response);
},
};
};
template.js
const fs = require("fs");
const path = require("path");
// {name:'sangbeom'}
module.exports = (filename, obj = {}, defaultDir = "../views") => {
// obj = {name:'sangbeom', title:"메인 페이지 입니다."}
console.log(obj);
const target = path.join(__dirname, defaultDir, filename);
let readline = fs.readFileSync(target, "utf8"); // html string에 해당함!!
// Javascript 스펙
// String.prototype.replaceAll(찾을 단어, 바꿀 단어)
// let text = readline.replaceAll("{{name}}", obj.name);
// text = text.replaceAll("{{title}}", obj.title);
for (const key in obj) {
// key = name, obj[key] = 'sangbeom'
readline = readline.replaceAll(`{{${key}}}`, obj[key]);
// console.log(key, obj[key]); // 확인용 코드
}
return readline;
};
static.js
const fs = require("fs");
const path = require("path");
const root = "../public";
const rootDir = path.join(__dirname, root);
let result = {};
const find = (currentPath) => {
// "css js images 1.js" 찍기
const directory = fs.readdirSync(currentPath);
for (const index in directory) {
const findPath = path.join(currentPath, directory[index]);
const isFile = fs.statSync(findPath).isFile(); // file일 경우: true, directory일 경우: false
if (!isFile) {
// directory일 경우
find(findPath);
} else {
// file일 경우
const key =
currentPath === rootDir ? "/" : currentPath.replaceAll(rootDir, "");
const httpPath = path.join(key, directory[index]);
result[httpPath] = directory[index];
// directory[index] = 파일명
// findPath = currentPath + directory[index]
}
}
return result;
};
// const a = find(rootDir);
// console.log(a);
module.exports = find(rootDir); // 결과값으로 "객체({})"를 반환해 줌!!
write.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
write 페이지 입니다.
<form method="post" action="/write">
<input type="text" name="subject" />
<button type="submit">버튼~~~</button>
</form>
</body>
</html>
+) 용어 정리
중간에 낀 서버 혹은 코드가 "미들웨어"이다!!
조건문처럼 어떤 요청이 들어왔을 때 어떤 것을 실행할지 어떤 것을 보낼지 결정하는 것(코드)을 "Router"라 한다!!
'Node.js' 카테고리의 다른 글
Node.js(9) - express를 활용한 게시판 구현 (0) | 2022.12.19 |
---|---|
Node.js(8) - express (0) | 2022.12.14 |
Node.js(6) - HTTP, Node.js 내부 카테고리, file system, HTML 불러오기 (0) | 2022.12.12 |
Node.js(5) - TCP, HTTP(Request Message / Response Message), express (0) | 2022.12.09 |
Node.js(4) - TCP, 프로토콜, request message / response message (0) | 2022.12.08 |