막하는스터디 두번째만남 express(20151025)
TRANSCRIPT
오늘은 장표 보다는 expressjs.com 의 API Reference 사이트를 중심으로 공부해 봐요!
Node.js 기반의 작고 유연성 있는웹/모바일 애플리케이션을 만들 수 있는 프레임워크
Source : http://expressjs.com/
http://expressjs.com 에서 보다 자세한 이야기를…
npm install express-generator –g
Source : http://expressjs.com/starter/generator.html
템플릿엔진으로 EJS를사용.
앱폴더에서아래명령으로파일준비
express --ejs
아래명령으로설치진행
npm install
아래명령을통해앱을구동
그리고 http://127.0.0.1 으로접속
Express 없이만들어봤던, 폼페이지를만들어봅니다.
app.js 파일을열어, 앞서만든 route 파일을연결해줍니다.
routes 에서지정한템플릿파일을 views 폴더에 .ejs 파일확장자를붙여만든다.
* 정적인콘텐츠는 public 폴더에두고, 사용합니다.
routes 폴더에 URL을정의해둘 JS 파일을만든다.
이름, 이메일, 하고싶은말등을입력할수있는폼을제공하는/hello/form 을만듭니다.
/hello/formSubmit 이라는주소로,
POST 메서드로전송하게하고,
전송받은내용을다시출력해봅니다.
URL을정의하고, 어떤 View를사용할지, 어떤데이터를 View에서사용할수있도록할지정의합니다.
MVC 디자인패턴에서, Controller에해당한다고볼수있습니다.
Express.js API를 공부하다보니, 지난시간에파라미터값을받는과정이더이상유효하지않다는사실을알았어요! 위와같이변경해야한답니다.
require()를통해작성한 hello 모듈을불러오고, 이것을 app.use()를통해,
/hello 아래에연결시켜줍니다.
컨트롤러에서전달한변수를출력할때에는 <%=변수명%>으로 작성하면됩니다.
변수값에서 < , > , & , “ 등의값은각각 < , > , & , " 등으로치환되는데, (XSS 문제때문에)
원본그대로출력하고할때에는, <%-변수명%>으로 작성합니다.
Express에서 제공하는 API에 대해,활용법을 확인할 수 있습니다.
Express.js.com의 API reference 메뉴를 클릭!
Source : http://expressjs.com/4x/api.html
Source : http://expressjs.com/4x/api.html
var express = require('express');var app = express();
Express 애플리케이션을 만들기 위해서는, 아래 2줄을 작성하는 것에서 부터 시작됩니다.
HTTP 요청에대한, 라우팅기능
미들웨어(middleware) 설정기능
HTML View 렌더링기능
템플릿엔진등록기능
메인앱
서브앱 서브앱 서브앱
Request
Response
클라이언트로부터 받은 정보들을 접근할 때
클라이언트에게 정보를 제공할 때
Application 애플리케이션 전체에 관한 정보를 접근할 때
Router 라우터 기반의 미들웨어를 만들 때(서브 앱)
app.locals
app.mountpath
애플리케이션 내 지역 변수로 사용 할 수 있음.
서브 애플리케이션이 메인 애플리케이션의어느 경로에 마운트되었는지 확인할 때 사용할 수 있음.
app.locals.title = 'My App';app.locals.email = '[email protected]';
app.js 에 아래와 같이 추가해 주세요.
<%=title%><%=email%>
그리고 지난 시간에 만든, form.ejs 파일에 아래와 같이 변수 값을 출력하도록 추가해 보세요.
그리고, node bin\www 명령으로 express 애플리케이션을 구동하세요.
앱 전역에 선언된 변수로, ejs 템플릿 내에서도 사용할 수 있어요.
app.locals.title = 'My App';app.locals.email = '[email protected]';
아래와 같이 애플리케이션 변수를 만들어 사용하는 것과,
title = 'My App';email = '[email protected]';
아래와 같이 전역 변수를 선언 후, 사용하는 차이는?
<%title = “Your App”;email = “Your email address”;
%>
<%=title%><%=email%>
form.ejs 파일에 아래와 같이 변수 값을 다른 값으로 대입하는 코드를 넣어서 테스트 해 봐요.
어떤 변화가 있는지!
차이를 알게 되었다면, 어떤 경우에 쓰면 될까 생각해 봐요!
var admin = express();admin.on('mount', function (parent) {
console.log('Admin Mounted');console.log(parent); // refers to the parent app
});
admin.get('/', function (req, res) {res.send('Admin Homepage');
});
app.use('/admin', admin);
Source : http://expressjs.com/4x/api.html
이벤트가 발생하면, 어떻게 할지 정의할 수 있어요.
(그런데... 오늘은 우리가 쓸 일이 없는 듯…)
app.disable(), enable() 애플리케이션 설정의 사용 유무를 변경 할 때
app.disabled(), enabled() 애플리케이션 설정 상태를 확인 할 때
app.set() , app.get() 애플리케이션 설정 값을 변경 할 때
app.engine() 템플릿 엔진을 등록 할 때
app.path() 서브 애플리케이션이 마운트된 경로를 확인할 때
app.use() 미들웨어를 현재 애플리케이션에 마운트 할 때
app.param() 특정 파라미터에 대한 처리가 필요 할 때
app.render() HTML 렌더링이 필요할 때 사용
app.route() HTTP 동작에 대한 라우트 설정할 때
app.all() … get() , post() , delete() , put() HTTP 요청별 처리할 내용을 기술 할 때
app.listen() 노드의 http.Server.listen()과 같음.
http://expressjs.com/4x/api.html#app.settings.table
아래 사이트에 방문해 확인해 봐요.
간단한 예로, 경로의 대/소문자를 구별할지 여부를 지정할 수 있어요!
(참고로 기본 값은 구별하지 않도록 되어 있어요)
app.disable('trust proxy');app.get('trust proxy');// => false
app.enable('trust proxy');app.get('trust proxy');// => true
disable(“속성 명”) 은 해당 속성을 사용하지 못하도록 할 때
enable(“속성 명”) 은 해당 속성을 사용 할 수 있도록 할 때
예시의 trust proxy 의 경우, 프록시 서버를 통해 접근하는 것에 대한 신뢰 여부인데, 기본적으로 X-Forwarded- 로 시작하는 헤더로 오는 정보를 신뢰할 것인지 설정합니다. ( 이후 장표에서 자세히 …)
disabled(“속성 명”) 은 해당 속성이 사용하지 못하도록 되어 있는지 확인 할 때 사용합니다.
app.disabled('trust proxy');// => true
app.enable('trust proxy');app.disabled('trust proxy');// => false
enabled(“속성 명”) 은 해당 속성이 사용 가능하도록 되어 있는지 확인 할 때 사용합니다.
app.enabled('trust proxy');// => false
app.enable('trust proxy');app.enabled('trust proxy');// => true
set(“속성 명”) 은 해당 속성의 값을 바꿀 때,
get(“속성 명”)은 해당 속성의 값을 획득할 때 사용
app.set('view engine', ‘ejs');
app.get('view engine');// "My Site"
예시의 view engin은 뷰 템플릿 엔진의 종류를 설정할 때 사용합니다.
파일과 템플릿 엔진을 연결할 때 사용
app.engine('jade', require('jade').__express);
app.engine('html', require('ejs').renderFile);
EJS 템플릿 파일도 위와 같은 방식으로, html 확장자를 가진 파일로 연결시킬 수 있어요!
미들웨어를 현재 애플리케이션에 연결할 때 사용할 수 있어요.경로를 생략하면, “/”에 마운트됩니다.
app.use('/admin', function(req, res, next) {// GET 'http://www.example.com/admin/new‘console.log(req.originalUrl); // '/admin/new‘console.log(req.baseUrl); // '/admin‘console.log(req.path); // '/new‘next();
});
next()가 없으면 어떤 일이 일어날까요?
경로에 대한 단일 라우터를 만들 때 사용 가능하나의 경로에 대해 중복해서 여러 HTTP 메서드 처리를 등록하는 경우, 유용하게 사용 가능.
var app = express();app.route('/events').all(function(req, res, next) {// 모든 HTTP 메서드에 대해 대응
}).get(function(req, res, next) {// GET 메서드에 대해 대응
}).post(function(req, res, next) {// POST 메서드에 대해 대응
})
주소에서 사용되는 파라미터에 대한 트리거를 걸 때 사용함.
app.param('user', function(req, res, next, id) {// 사용자 상세 정보를 사용자 모델을 호출해 획득한다.User.find(id, function(err, user) {if (err) {next(err);
} else if (user) {req.user = user;next();
} else {next(new Error('failed to load user'));
}});
});
(예시) http://www.somestudy.com/user/caoy
User라는모델이 있다고가정하고,
모든 HTTP 메서드에 대해 대응해야 할 때 사용
app.all('*', requireAuthentication, loadUser);
app.all('*', requireAuthentication)app.all('*', loadUser);
all() 메서드외 get() , post() , put(), delete() 메서드가 있어요!
그런데, get() 메서드가 겹치네요? 아까 뭐라고 배웠더라~
제목에서 나열한 메서드는 모두 콜백 함수가 있는데, 콜백 함수가 받는 인자는 아래 형태로 모두 같아요!
function(req, res, next, value) {
// 첫 번째 자리로 전달되는 인자는 Request 오브젝트
// 두 번째 자리로 전달되는 인자는 Response 오브젝트
// 세 번째 자리로 전달되는 인자는 다음으로 실행될 오브젝트
// 네 번째 자리로 전달되는 인자는 파라미터 값(param()에서만!)
}
필요에 따라, 콜백 함수에서 인자를 받는 것을 생략할 수 있습니다.
req.app /
res.app
req.baseUrl
메인 애플리케이션에 접근할 때
URL 경로가 어디에 마운트되었는지 확인 할 때
req.bodykey-value 쌍의 전송 받은 데이터 (기본 값은 undefined)body-parser 혹은 multer 모듈을 미들웨어로 사용할 수 있음
req.cookies 웹 브라우저가 보내 온 쿠키 정보를 확인 할 때
req.ip /
Req.ips클라이언트의 IP주소를 획득할 때
req.originalUrl
req.params
접속한 전체 주소를 확인할 때(경로 부분+쿼리스트링)
경로에 포함된 파라미터 값을 획득 할 때
req.path 접속 한 주소에서 경로 부분을 확인 할 때
req.query 접속한 주소에서 쿼리스트링으로 전달 된 값을 획득 할 때(GET방식)
req.xhr XHR 호출인지 여부를 구분할 때(헤더의 X-Requested-With로 판별)
res.headerSent
res.locals
웹 브라우저로 헤더가 전송되었는지 여부
응답용 지역 변수로, app.locals과 동일
req.get(“필드명”) 웹브라우저가 보내온 헤더의 특정 필드 값을 획득 할 때
accepts(), acceptsCharsets(), acceptsEncodings() 등등과 같은메서드가 몇 개 있지만… 실제 활용율이 떨어져서 생략합니다.
res.append(“필드명” [ , “값 ” ] )
= res.set() , res.header()웹브라우저로 응답하는 헤더에 추가 할 때
res.attachment( [ “파일명” ] ) 파일 다운로드(첨부형식) 헤더를 추가할 때
res.cookie( “쿠키명“ , “값” [ , 옵션객체] ) 쿠키를 설정할 때
res.clearCookie( “쿠키명 ” ) 쿠키를 삭제할 때
res.download( 파일경로 [, “파일명” ] [, 함수 ] ) 파일 다운로드를 처리할 때
res.end( [ “데이터” ] ) 웹 브라우저로 보낼 데이터(문자열) & 종료
res.json ( [ 객체 ] ) JSON 형식으로 응답할 때
res.jsonp ( [ 객체 ] ) JSONP 형식으로 응답할 때 (?callback=)
res.location ( “이동될주소” )
res.redirect( [상태코드,] , “이동될주소”)특정 주소로 리디렉트 처리 할 때
res.render( “뷰파일 ” [, 지역변수] [, 콜백] ) HTML 렌더링을 할 때
res.send( “내용” ) 웹 브라우저로 보낼 데이터(문자열)
res.sendStatus( 응답코드 ) HTTP 응답 코드를 설정 할 때
res.type(“파일확장자혹은 MIME타입”) 응답 콘텐츠에 대한 콘텐츠 타입 지정할 때
작업중버전