node.js에서 콘솔에 출력을 하기 위한 문법은 다음과 같다.
console.log(값)//값에는 1+1, 2*3과 같은 수식도 들어갈 수 있다.
변수를 표시할 때에는 별다른 표시 없이 파이썬과 마친가지로 선언한다.
a=1
console.log(a);//1
a="hello"+" world";
console.log(a);//hello world

http:웹 서버가 데이터를 주고받기 위해 만든 통신 규칙
opentutorials.org: 특정한 인터넷에 연결되어있는 컴퓨터를 나타내는 주소
3000: 포트 번호, 기본값은 80이다.
main: 경로를 나타낸다. 컴퓨터 안에 있는 어떤 디렉토리의 어떤 파일인지를 나타낸다.
id=HTML&page=12: 쿼리 스트링이다. 웹서버에 데이터를 전달할 수 있다. html에서 12페이지를 읽는다는 뜻이다.
var http = require('http');//모듈
var fs = require('fs');//모듈
var url = require('url');//모듈
var app = http.createServer(function(request,response){
var _url = request.url;
var queryData=url.parse(_url,true).query;
console.log(queryData.id);
if(_url == '/'){
url = '/index.html';
}
if(_url == '/favicon.ico'){
return response.writeHead(404);
}
response.writeHead(200);
response.end(queryData.id);//파일들을 읽어주는 코드
});
app.listen(3000);
이 코드를 실행하면 querydata의 id인 html이 웹페이지에 출력된다.
Create Read Update Delete의 약자이다.
var fs=require('fs');
fs.readFile('sample.txt', 'utf8', function(err,data){});
이대로 실행시키게 된다면 node js의 상위 디렉토리에서 실행된 것이기 때문에 아무것도 출력되지 않는다. 이럴 경우에는 cd(Change Directory)를 사용하면 sample.txt에 적힌 문장을 읽어올 수 있다.
기본적인 nodejs의 문법은 javascript와 동일하기 때문에 조건문, 제어문, 반복문 등은 적지 않았습니다.
var args=progress.args;
console.log(args);
이 코드를 실행하고 node (파일의 위치) (입력값)을 콘솔에 입력하면 3개의 원소가 있는 배열이 출력된다.
원소는 각각 nodejs의 런타임이 어디에 있는지에 관한 정보, 파일을 실행시킨 경로, 입력값이 담겨있다.
url.parse(_url,true)는 url의 정보를 담고있다. 이를 활용해서 url이 잘못된 경로로 들어가졌을 때 not found가 출력되도록 구현할 수 있다.
var pathname=url.parse(_url,true).pathname;
if(pathname==='/'){
//본문 내용
}
else{
response.writeHead(404);//404는 오류를 표현할 때 약속된 숫자이다.
response.end('Not Found');
}

홈페이지에 들어가면 위의 사진과 같이 출력된다. 물론 HTML,CSS,JavaScript를 클릭하면 그에 대한 정보가 나오긴 하지만 그게 아닐 경우 홈페이지의 화면이 정상적으로 출력되게 나오려면 조건문을 활용하여야 한다.
var queryData=url.parse(_url,true).query;
if(queryData==undefined){
//나오게할 홈페이지 분문 내용
}
else{
//본문 내용
}
위의 코드를 활용하는 식으로 홈페이지 구현이 가능하다.
var testFolder='./data';
var fs=require('fs');
fs.readdir(testFolder, function(error, filelist){
console.log(filelist);
})
//출력 결과:['CSS', 'HTML', 'JavaScript']
위의 코드는 파일의 목록을 배열의 형식으로 나타내어 전달하는 코드이다. 이를 활용하여 글 목록을 간편화시켜 출력할 수 있다.
var list='<ul>';
var i=0;
while(i<filelist.length){
list=list+'<li><a
href="/?id=${filelist[i]}">${filelist[i]}</a></li>';
i=i+1;
}
list=list+'</ul>';

동기적: 어떠한 일이 끝나야 다음 일을 실행시키는 것을 말한다.
비동기적: 어떠한 일이 끝나기 전에 다른 일을 동시에 하는 것을 말한다. 이는 매우 효율적이지만 복잡하다. Nodejs에서는 비동기적인 작업을 주로 다룬다. 코드로 설명하면 다음과 같다.
var fs=require('fs');
console.log('A');
var result=fs.readFileSync('syntax/sample.txt','utf8');
console.log(result);
console.log('C');
위의 코드는 파일을 동기적으로 읽고 실행시키는 코드이다. 순차적으로 코드를 읽기 때문에 출력으로는 A,B,C가 순서대로 출력된다. 비동기는 다음과 같다.
var fs=require('fs');
console.log('A');
var result=fs.readFileSync('syntax/sample.txt','utf8',function(err,result){console.log(result);} );
console.log('C');
위의 코드는 출력이 A,C,B가 되는데 이는 비동기적으로 B보다 C가 더 빨리 출력된 것이다.
<form action="http::localhost:3000/process_create"
method="post">//적혀있는 주소에 내용을 숨긴상태로 보내는 코드
<p><input type="text" name="title"></p>//무엇을 입력할 것인지
<p>
<textarea name="description"></textarea>//입력 줄을 여러개로 하는 콛
</p>
<p>
<input type="submit">//전송버튼
</p>
</form>
이 코드를 작성한 후 본문에다 if(pathname==='/create')를 활용해서 코드를 추가시겨주면 정상적으로 작동하는 것을 확인할 수 있다.
else if(pathname === '/create_process'){
var body = '';
request.on('data', function(data){//정보들을 수신할 때 마다 서버는 function(data) 콜백함수를 수신하고 data라는 인자를 통해서 수신한 정보를 준다.
body = body + data;//그리고 body에 데이터를 추가한다.
});
request.on('end', function(){//들어오는 정보가 없으면 end에 해당하는 콜백함수를 실행시킨다.
var post = qs.parse(body);//body에 받아온 정보들을 qs.parse를 통해 post에 저장한다.
var title = post.title;
var description = post.description
});
response.writeHead(200);
response.end('success');
}
else if(pathname === '/create_process'){
var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var title = post.title;
var description = post.description;
fs.writeFile(`data/${title}`, description, 'utf8', function(err){//입력한 데이터의 제목, 본문내용을 data에 저장
response.writeHead(302, {Location: `/?id=${title}`});//저장을 완료시킨 후 입력한 정보를 볼 수 있는 사이트의 경로로 이동시켜 준다.
response.end();
})
});
이 코드를 실행시키고 웹에서 create를 통해 정보를 입력하면 data에 입력한 정보가 저장된다.
else if(pathname === '/update'){
fs.readdir('./data', function(error, filelist){
fs.readFile(`data/${queryData.id}`, 'utf8', function(err, description){
var title = queryData.id;
var list = templateList(filelist);
var template = templateHTML(title, list,
`
<form action="/update_process" method="post">// update_process로 수정한 내용을 전달한다.
<input type="hidden" name="id" value="${title}">//hidden으로 원래 이름을 숨김상태로 전달한다.
<p><input type="text" name="title" placeholder="title" value="${title}"></p>
<p>
<textarea name="description" placeholder="description">${description}</textarea>
</p>
<p>
<input type="submit">
</p>
</form>
`,
`<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
);
response.writeHead(200);
response.end(template);
});
});
} else if(pathname === '/update_process'){
var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var id = post.id;
var title = post.title;
var description = post.description;
fs.rename(`data/${id}`, `data/${title}`, function(error){//raname은 첫번째 인자를 두번째 인자로 바꾸는 역할을 수행한다.
fs.writeFile(`data/${title}`, description, 'utf8', function(err){
response.writeHead(302, {Location: `/?id=${title}`});
response.end();
})
});
글을 update하는 것은 create 기능을 만들 때 사용했던 코드를 조금만 수정하면 만들 수 있다. update_process로 원래 id와 수정할 title, 수정할 본문을 보내주고 rename함수를 통해 이름을 바꾼 후 내용을 저장하는 방식이다.
글 삭제는 앞서 배웠던 create와 update와 같이 링크로 구현하지 않고 폼으로 만들어야 한다.
<form action="delete_process" method="post">
<input type="hidden" name="id" value="${title}">
<input type="submit" value="delete">
</form>`
else if(pathname === '/delete_process'){
var body = '';
request.on('data', function(data){
body = body + data;
});
request.on('end', function(){
var post = qs.parse(body);
var id = post.id;//다른 기능들과는 달리 삭제는 id만을 필요로 한다.
fs.unlink(`data/${id}`, function(error){
response.writeHead(302, {Location: `/`});
response.end();//unlink는 해당 id에 저장된 본문 내용을 삭제하는 역할을 한다.
})
});
객체는 배열과 비슷하지만 다르다. 배열은 순서가 있고 이는 인덱스로 구성되어 있다. 그것을 요소라고 하며 대괄호로 배열을 만든다.
객체는 키와 값으로 구성되어 있다. 이것을 속성이라고 하며 한 쌍당 쉼표로 구분한다. 배열과 달리 객체는 중괄호로 만들 수 있다. 값을 선언할 때에는 객체의 이름 뒤에 온점을 붙인 후 키를 입력하면 그에 맞는 값이 출력된다. 예를 들면 객체는 다음 코드로 선언할 수 있다.
user={name:"jangwoojin", city:"incheon"};
console.log(user.name);//jangwoojin
또한 객체 안에 함수를 추가해 이를 호출할 수도 있다.
var q = {
v1:'v1',
v2:'v2',
f1:function (){
console.log(this.v1);//this는 객체의 이름을 가리키는 약속된 문자이다. 이를 통해서 만약 객체의 이름이 바뀌었을 때 객체 내에 있는 모든 객체 이름을 바꾸지 않아도 되는 효과를 볼 수 있다.
},
f2:function(){
console.log(this.v2);
}
}
q.f1();
q.f2();
var M = {
v:'v',
f:function(){
console.log(this.v);
}
}
module.exports = M;//module.export=M은 M이 가리키는 객체를 바깥에서 사용할 수 있게 해준다.
var part = require('./mpart.js');//모듈을 가져올때는 require을 사용해서 경로를 입력해 주면 된다.
part.f();//v
이를 통해서 app의 템플릿을 다른 폴더로 빼놓을 수 있다.
module.exports = {
HTML:function(title, list, body, control){
return `
<!doctype html>
<html>
<head>
<title>WEB1 - ${title}</title>
<meta charset="utf-8">
</head>
<body>
<h1><a href="/">WEB</a></h1>
${list}
${control}
${body}
</body>
</html>
`;
},list:function(filelist){
var list = '<ul>';
var i = 0;
while(i < filelist.length){
list = list + `<li><a href="/?id=${filelist[i]}">${filelist[i]}</a></li>`;
i = i + 1;
}
list = list+'</ul>';
return list;
}
}
이 폴더 내의 템플릿을 사용하려면 var template=require('./lib/template.js');
과 같이 require을 사용해 모듈을 불러오면 된다.