-
생활코딩 WEB2 - #1 Node.js 동적인 웹페이지 만들기Node.js/생활코딩-WEB2 2020. 4. 22. 23:26
출처: 생활코딩 WEB2 - Node.js
https://opentutorials.org/course/3332정적 웹 페이지
index.html
<!doctype html> <html> <head> <title>WEB1 - Welcome</title> <meta charset="utf-8"> </head> <body> <h1><a href="index.html">WEB</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> <h2>WEB</h2> <p> The World Wide Web (abbreviated WWW or the Web) is an information space where documents and other web resources are identified by Uniform Resource Locators (URLs), interlinked by hypertext links, and can be accessed via the Internet.[1] English scientist Tim Berners-Lee invented the World Wide Web in 1989. He wrote the first web browser computer program in 1990 while employed at CERN in Switzerland.[2][3] The Web browser was released outside of CERN in 1991, first to other research institutions starting in January 1991 and to the general public on the Internet in August 1991. </p> </body> </html>
이렇게 index.html 처럼 저장된 그대로 보이는걸 정적인 웹이라고 한다. 🤔
사실 정적인 웹은 동적인 웹을 보기 전까진 잘 이해가 안 간다.
동적 웹 페이지
var app = http.createServer(function (request, response) { var _url = request.url; var queryData = url.parse(_url, true).query; //querystring 가져오기 var title = queryData.id if (_url == '/') { title = "Welcome" } if (url == '/favicon.ico') { response.writeHead(404); response.end(); return; } response.writeHead(200); fs.readFile(`data/${title}`, 'utf8', (err, description) => { var template = ` <!doctype html> <html> <head> <title>WEB1 - HTML</title> <meta charset="utf-8"> </head> <body> <h1><a href="/">WEB - ${title}</a></h1> <ol> <li><a href="?id=HTML">HTML</a></li> <li><a href="?id=CSS">CSS</a></li> <li><a href="?id=JavaScript">JavaScript</a></li> </ol> <h2>${title}</h2> <p> ${description} </p> </body> </html> ` response.end(template); }) });
이건 동적 웹 페이지 예시이다.
template 변수 안에는 index.html 과 비슷한 형태로 HTML 태그가 구성되어있다. 그런데 <h1> 태그와 <h2> 태그, <p> 태그를 보면 index.html처럼 내용이 고정되어 있는 게 아니라 title과 description 변수의 값을 보여주게끔 되어있다.
즉, 태그안의 내용이 코드에 고정되어 있지 않고 변수의 값에 따라 바뀔 수 있다. 이런 걸 동적 웹페이지라고 한다.
그럼 동적 웹페이지는 왜 필요할까?
1.html 부터 10.html 까지 정적 웹페이지가 있다고 상상해보자. 각 페이지는 <h1> 태그 밑에 <ul> 태그가 있고 글 목록이 보이고 있다.
<body> <h1><a href="index.html">WEB</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> ... <li><a href="10.html">Node.js</a></li> </ul> <h2>WEB</h2> <p> ... </p> </body>
어느 날, 과장님께서 <ul> 로 되어있던 태그를 <ol> 로 바꾸자고 하신다. 10개쯤이야 뭐... 하면서 모든 페이지의 <ul> 태그를 <o1> 로 고쳤다.
시간이 흘러 10.html까지 있던 페이지는 500.html까지 생겼다. 그런데 이번에는 과장님이 다시 <ol> 를 <u1> 로 바꾸라고 하신다😳야근각이다
동적 웹페이지로 만들면 500개의 페이지를 수정할 필요 없이 하나의 파일만 수정하면 된다.
어떻게 500개의 파일이 아닌 하나만 수정해도 되는 건지 Node.js로 동적 웹페이지를 만들면서 알아가 보자
Node.js 웹 서버 만들기
// main.js var http = require('http'); var app = http.createServer(function (request, response) { var url = request.url; response.writeHead(200); response.end(url); }); app.listen(3000);
이 코드는 웹서버를 만드는 코드이다.
main.js를 node.js로 실행 후 http://localhost:3000에 접속해보면 '/'가 화면에 나오고 있는 걸 볼 수 있다.
(클라이언트가 http://localhost:3000으로 요청하니 서버가 / 라고 응답해줬다.)
이번엔 숫자 3000 (3000포트) 뒤에 /home 으로 입력하니 화면에도 똑같이 /home이 나왔다.
왜냐하면 웹 서버 코드에 클라이언트가 요청한 주소를 그대로 응답하도록 되어있기 때문이다.
var app = http.createServer(function (request, response) { var url = request.url; // 클라이언트가 요청한 주소를 response.writeHead(200); response.end(url); // 서버가 그대로 응답 });
정확히는 클라이언트가 요청한 전체 URL에서 프로토콜, 포트를 제외한 나머지를 응답해주고 있다.
URL 구조
URL(Uniform Resource Locator)은 네트워크 상에서 자원이 어디 있는지를 알려주기 위한 규약이다. - 위키백과
(어려우니 지금은 인터넷에서 어느 사이트에 접속하기 위해서 입력해야 하는 주소라고만 생각하자)http://kanhi.tistory.com:80/index.html?id=HTML&page=12#bookmark 이런 URL이 있다고 하자. URL의 구조는 아래와 같다.
1. 프로토콜: 사용자가 서버에 접속할 때 어떤 방식으로 접속할 것 인가를 결정
2. 도메인: 어떤 웹 서버가 요구되는 것인 지를 가리킴
3. 포트: 한 대의 컴퓨터 안에 여러 대의 서버가 있을 수 있음. 클라이언트가 접속했을 때 그중 어떤 서버와 통신할지를 결정
5. 경로: 어떤 폴더의 어떤 파일인지 가리킴
6. 쿼리스트링: 웹서버에게 데이터를 전달할 수 있음. 쿼리 스트링의 시작은?로 시작, 값의 구분은 &으로 구분
복잡하다😢 나중에 동적 웹 페이지를 제공할 때 쿼리스트링으로 ID를 받아서 페이지를 보여줄 거니 지금은 쿼리 스트링만 기억하자
정적 웹 페이지 제공
그럼, 먼저 웹 서버가 정적 웹 페이지를 제공하도록 구현해보자.
main.js가 있는 폴더에 index.html 파일을 만들었다.
<!doctype html> <html> <head> <title>WEB1 - Welcome</title> <meta charset="utf-8"> </head> <body> <h1><a href="index.html">WEB</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> <h2>WEB</h2> <p> Web is... </p> </body> </html>
이때까지 이 index.html 파일을 열려면 직접 이 파일이 있는 폴더로 가서 파일을 더블클릭 해 열어야 했다.
그런데 이번에는 그 방법 말고 브라우저 주소 표시줄에 http://localhost:3000/index.html 을 입력하면 열리도록 코드를 수정해보자.
// main.js var http = require('http'); var fs = require('fs'); // 추가 var app = http.createServer(function (request, response) { var url = request.url; response.writeHead(200); response.end(fs.readFileSync(__dirname + url)); // 추가 }); app.listen(3000);
main.js 에 fs와 관련된 코드를 추가한 후 node를 재시작하고 http://localhost:3000/index.html 에 접속해보니 잘 나온다.
이런 식으로 1.html 이 나오게 하고 싶다면 1.html 파일을 만들고
<!doctype html> <html> <head> <title>WEB1 - HTML</title> <meta charset="utf-8"> </head> <body> <h1><a href="index.html">WEB</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> <h2>HTML</h2> <p> HTML is ... </p> </body> </html>
브라우저에서 http://localhost:3000/1.html 입력하면
마찬가지로 잘 나온다.
fs.readFileSync(__dirname + url);
이 코드는 파일을 읽는 코드이다.
__dirname(_2개)은 main.js가 있는 실제 위치를 뜻한다.
예를 들어 main.js이 Documents폴더 안에 있는 study폴더 안에 있는 post 폴더에 있다면 console.log로 __dirname을 찍었을 때
Documents/study/post
라고 나올 것이다.
index.html은 main.js와 같은 경로에 있기 때문에 __dirname + url 은 곧 'Documents/study/post' + '/index.html'을 뜻한다.
그렇기 때문에 주소창에서 http://localhost:3000/index.html 을 입력하면 readFileSync 함수의 인자로
Documents/study/post/index.html을 전달하는 거와 동일하다.
fs.readFileSync('Documents/study/post/index.html');
동적 웹 페이지 만들기
var http = require('http'); var fs = require('fs'); var app = http.createServer(function (request, response) { var url = request.url; var template = ` <!doctype html> <html> <head> <title>WEB1 - Welcome</title> <meta charset="utf-8"> </head> <body> <h1><a href="index.html">WEB</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> <h2>WEB</h2> <p> Web is... </p> </body> </html> ` response.writeHead(200); response.end(template); // 수정 }); app.listen(3000);
main.js 에서 response.end(fs.readFileSync(__dirname + url)); 로 되어있던 부분을 template 변수를 받게끔 수정하고 template 변수에는 index.html 에 있던 내용을 그대로 복사해 붙여 넣는다.
그리고 node 재실행 후 http://localhost:3000에 접속해보면 잘 나온다.
URL을 통해서 입력된 값 사용하기
이번엔 쿼리스트링으로 받은 id를 페이지에 출력해보자.
쿼리스트링은 http://localhost:3000/?id=html 이 URL을 예로 들면 물음표(?) 뒤에 있는 id=html을 뜻한다.
var http = require('http'); var fs = require('fs'); var url = require('url'); // 추가 var app = http.createServer(function (request, response) { var _url = request.url; // 변수명을 url에서 _url로 변경 var queryData = url.parse(_url, true).query; // 추가 console.log(queryData) // {id: 'html'} var title = queryData.id; // 추가 var template = ` <!doctype html> <html> <head> <title>WEB1 - Welcome</title> <meta charset="utf-8"> </head> <body> <h1><a href="index.html">WEB - ${title}</a></h1> <ul> <li><a href="1.html">HTML</a></li> <li><a href="2.html">CSS</a></li> <li><a href="3.html">JavaScript</a></li> </ul> <h2>${title}</h2> <p> ${title} is... </p> </body> </html> ` response.writeHead(200); response.end(template); }); app.listen(3000);
쿼리스트링을 받기 위해서는 url 모듈을 사용해야 한다. 상위에 var url = require('url'); 를 추가해주는데
이미 createServer 함수 내부에서 url 이라는 변수를 쓰고 있다. 그래서 createServer 함수 안에 있는 url은 _url로 이름을 변경해준다.
var queryData = url.parse(_url, true).query; 으로 쿼리스트링을 queryData에 넣어주고
console.log로 queryData를 찍어보면 쿼리스트링 매개변수를 id로 받았으니 {id: 'html'}로 나오는 걸 확인할 수 있다.
파라미터로 받은 id값을 title 변수에 넣어주고 var title = queryData.id
template 변수에서 <h1>, <h2>, <p> 태그 쪽에 title 변숫값이 나오도록 수정했다.
http://localhost:3000/?id=html 로 접속해서 결과를 보면 URL에서 쿼리스트링으로 id = html을 전달하니 웹 페이지에도 그대로 나온다.
이번엔 id를 css로 전달 후 확인해보면 마찬가지로 웹 페이지에 css가 나온다
이제 500개가 넘는 페이지의 모든 <ul>태그를 <ol>로 변경하려면 main.js 파일 하나만 수정하면 된다 🎉