> 웹 프론트엔드 > JS 튜토리얼 > Nodejs Express4.x 개발 프레임워크 Notes_node.js

Nodejs Express4.x 개발 프레임워크 Notes_node.js

WBOY
풀어 주다: 2016-05-16 15:30:41
원래의
1356명이 탐색했습니다.

Express: ?Node.js용 웹 애플리케이션 프레임워크?Express는 간결하고 유연한 node.js 웹 애플리케이션 개발 프레임워크로, 다양한 웹 및 모바일 장치 애플리케이션을 만드는 데 도움이 되는 일련의 강력한 기능을 제공합니다.

목차

이 기사에서는 Mongoose, Ejs, Bootstrap 및 기타 관련 콘텐츠가 포함된 Express4.x(구체적으로 4.10.4)의 개발 프레임워크에 중점을 둡니다.

프로젝트 만들기
디렉토리 구조
Express4.x 구성 파일
Ejs 템플릿 사용법
부트스트랩 인터페이스 프레임워크
라우팅 기능
세션 사용량
페이지 팁
페이지 접근 제어

개발 환경:

우분투

MonogoDB: v2.6.4

nodejs:v0.11.2

npm 2.1.10(nodejs가 1.2.19 버전으로 설치된 경우 이 글은 2.x 버전으로 업그레이드되었습니다.)

1. 프로젝트 생성

프로젝트 디렉토리를 입력하세요

mkdir 직장

CD작업장

express를 전역적으로 설치하면 express가 명령으로 시스템에 설치됩니다.

npm install -g express

익스프레스 버전 보기

익스프레스 -V

참고: express 명령은 express4.x 버전에 더 이상 포함되지 않습니다.

express-generator 설치 필요

npm install express-generator -g

자세한 설치 과정은 "Nodejs 개발 환경 Ubuntu 준비"를 참조하세요.

express 명령을 사용하여 프로젝트 생성 및 ejs 지원

hadoop@sven:~/workspace/nodeJs$ express -e nodejs-demo

생성: nodejs-demo(프로젝트 이름)
생성: nodejs-demo/package.json (프로젝트 패키지 정보)
생성: nodejs-demo/app.js(메인 프로그램)
생성: nodejs-demo/public(공용 디렉터리)
생성: nodejs-demo/public/images
생성: nodejs-demo/public/javascripts
생성: nodejs-demo/public/stylesheets
생성: nodejs-demo/public/stylesheets/style.css
create: nodejs-demo/routes(라우팅 디렉터리, 나중에 이 디렉터리에서 프로그램을 개발한 다음 app.js에서 사용)
생성: nodejs-demo/routes/index.js
생성: nodejs-demo/routes/users.js
생성: nodejs-demo/views(디렉토리 보기, 템플릿 파일 보기 등)
생성: nodejs-demo/views/index.ejs
생성: nodejs-demo/views/error.ejs
생성 : nodejs-demo/bin
생성: nodejs-demo/bin/www(app.js를 시작하는 데 사용되는 시작 파일)
종속성 설치:
$ cd nodejs-demo && npm 설치
앱을 실행하세요:
$ DEBUG=nodejs-demo ./bin/www

프로젝트가 성공적으로 생성되었습니다.

위 팁에 따라 종속성을 설치합니다.

코드 복사 코드는 다음과 같습니다.

cd nodejs-demo && npm 설치

안내에 따라 웹을 시작하세요.

코드 복사 코드는 다음과 같습니다.

$DEBUG=nodejs-demo ./bin/www

그러나 여기서는 이 방법을 사용하여 프로그램을 시작하지 않을 것입니다. 그 이유는 개발 과정에서 nodemon을 도구로 사용해야 하기 때문입니다.
Nodemon은 개발 프로세스 중에 프로젝트 변경 사항을 동적으로 식별한 다음 이를 동적으로 로드하는 데 사용됩니다(이는 Eclipse의 Java 웹 개발과 유사합니다). 이 도구는 웹 개발에 필수적입니다

nodemon 설치:

npm install nodemon -g

그럼 위의 ./bin/www 스크립트를 사용하면 어떨까요?

이유는 nodemon./bin/www가 프로젝트 변경 사항을 식별할 방법이 없기 때문입니다. (직접 실험해봤습니다. 혹시 아시는 전문가 계시면 조언 부탁드립니다)

app.js 수정:

마지막 줄을 주석 처리합니다. //module.exports = app

다음으로 대체: app.listen(3000);

app.js 기본 프로그램을 시작하려면 다음 명령을 사용하세요.

hadoop@sven:~/workspace/nodeJs/nodejs-demo$ nodemon app.js

그런 다음 프로그램을 수정하여 동적으로 로드되는지 확인하세요. 다음과 같은 메시지가 표시됩니다:

12월 1일 16:22:07 – [nodemon] 변경으로 인해 다시 시작…
12월 1일 16:22:07 – [nodemon] `node app.js` 시작

은 효력을 발휘한다는 의미입니다.

테스트:

로컬 포트 ​​3000이 열리고 브라우저를 통해 액세스됩니다: localhost:3000

2. 디렉토리 구조

./
drwxrwxr-x 5 hadoop hadoop 4096 12월 1일 15:57 ../
-rw-rw-r– 1 hadoop hadoop 1495 12월 1일 16:22 app.js
-rw-r–r– 1 hadoop hadoop 12288 12월 1일 16:22 .app.js.swp
drwxr-xr-x 2 hadoop hadoop 4096 12월 1일 15:57 bin/
drwxrwxr-x 9 hadoop hadoop 4096 12월 1일 15:58 node_modules/
-rw-rw-r– 1 hadoop hadoop 326 12월 1일 15:57 package.json
drwxr-xr-x 5 hadoop hadoop 4096 12월 1일 15:57 공개/
drwxr-xr-x 2 hadoop hadoop 4096 12월 1일 15:57 경로/
drwxr-xr-x 2 hadoop hadoop 4096 12월 1일 15:57 views/

디렉토리 소개:

node_modules는 모든 프로젝트 종속 라이브러리를 저장합니다. (각 프로젝트는 Maven, Gradle 등과는 다른 자체 종속성을 관리합니다.)
package.json, 프로젝트 종속성 구성 및 개발자 정보
app.js, 프로그램 메인 입구
공개, 정적 파일(css, js, img)
경로, 라우팅 파일(C, MVC의 컨트롤러)
뷰, 페이지 파일(Ejs 템플릿)
nodejs-demo/bin/www (app.js를 시작하는 데 사용되는 시작 파일)

app.js를 열어 콘텐츠 보기:

/**
* 模块依赖
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
//环境变量
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// 开发模式
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// 路径解析
app.get('/', routes.index);
app.get('/users', user.list);
// 启动及端口
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
로그인 후 복사

4. Ejs 템플릿 사용

ejs 템플릿 파일은 확장자가 html인 파일을 사용하도록 합니다.

수정: app.js

var ejs = require('ejs'); //ejs를 소개합니다. 종속성 다시 설치>
app.engine('.html', ejs.__express);
app.set('뷰 엔진', 'html'); // app.set('뷰 엔진', 'ejs');
이름 바꾸기: views/*.ejs를 views/*.html로 변경

localhost:3000에 접근하는 것이 맞습니다

index.ejs 등 주로 파일 이름을 바꿉니다

5. 부트스트랩 인터페이스 프레임워크 추가

실제로 js 및 css 파일을 프로젝트의 해당 디렉터리에 복사하면 됩니다. 4개 파일 포함:

public/stylesheets 디렉토리에 복사

bootstrap.min.css
bootstrap-responsible.min.css

public/javascripts 디렉토리에 복사

bootstrap.min.js
jquery-1.9.1.min.js

다음으로 index.html 페이지를 header.html, index.html, footer.html의 세 부분으로 나눕니다

header.html은 HTML 페이지의 헤더 영역입니다
index.html은 콘텐츠 표시 영역입니다
footer.html은 페이지 하단 영역입니다

header.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%=: title %></title>
<!-- Bootstrap -->
<link href="http://www.geedoo.info/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen">
<!-- <link href="http://www.geedoo.info/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen"> -->
</head>
<body screen_capture_injected="true">
index.html
<% include header.html %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<% include footer.html %>
footer.html
<script src="http://www.geedoo.info/javascripts/jquery-1.9.1.min.js"></script>
<script src="http://www.geedoo.info/javascripts/bootstrap.min.js"></script>
</body>
</html>
로그인 후 복사

localhost:3000에 접근하는 것이 맞습니다.

EJS 템플릿 기능을 성공적으로 사용하여 페이지에서 공개 머리글과 바닥글을 분리했습니다.

그리고 부트스트랩 인터페이스 프레임워크가 도입되었습니다.

6. 라우팅 기능

사용자 로그인 비즈니스 요구 사항을 설계해 보겠습니다.

접속경로 : /, 페이지 : index.html, 로그인 필요없이 바로 접속 가능합니다.
접속경로 : /home, 페이지 : home.html, 접속 전 반드시 사용자 로그인이 필요합니다.
접속 경로: /login, 페이지: login.html, 로그인 페이지, 사용자 이름과 비밀번호를 정확하게 입력하면 자동으로 home.html로 이동
접속경로 : /logout, 페이지 : 없음 로그아웃 후 자동으로 index.html 페이지로 돌아갑니다

app.js 파일을 열고 라우팅 구성을 추가하세요

app.get('/',routes.index);
app.route('/login')
.get(routes.login)
post(routes.doLogin);
app.get('/logout',routes.logout);
app.get('/home',routes.home);
로그인 후 복사

참고: get은 get 요청이고 post는 post 요청이며 all은 이 경로에 대한 모든 요청입니다.

routes/index.js 파일을 열고 해당 메소드를 추가합니다.

exports.index=function(req, res) {
 res.render('index', { title: 'index' });
};
exports.login=function(req,res){
 res.render('login',{title: '用户登录'});
};
exports.doLogin=function(req,res){
 var user = {
 username:"admin",
 password:"admin"
}
if(req.body.username==user.username && req.body.password==user.password){
 res.redirect('/home');
}
res.redirect('/login');
};
exports.logout = function(req,res){
 res.redirect('/');
};
exports.home = function(req,res){
 var user = {
 username:'admin',
 password:'admin'
 }
 res.render('home',{title:'Home',user:user});
};
로그인 후 복사

views/login.html과 views/home.html이라는 두 개의 파일을 만듭니다

login.html

<% include header.html %> 
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>
home.html:
<% include header.html %>
<h1>Welcome <%= user.username %>, 欢迎登陆!!</h1>
<a claa="btn" href="http://www.geedoo.info/logout">退出</a>
<% include footer.html %>
로그인 후 복사

index.html 수정 및 로그인 링크 추가

index.html

<% include header.html %>
<h1>Welcome to <%= title %></h1>
<p><a href="http://www.geedoo.info/login">登陆</a></p>
<% include footer.html %>
로그인 후 복사

路由及页面我们都写好了,快去网站上试试吧。

7. Session使用

从刚来的例子上面看,执行exports.doLogin时,如果用户名和密码正确,我们使用redirect方法跳转到的home

res.redirect('/home');

执行exports.home时,我们又用render渲染页面,并把user对象传给home.html页面

res.render('home', { title: 'Home',user: user});

为什么不能在doLogin时,就把user对象赋值给session,每个页面就不再传值了。

session这个问题,其实是涉及到服务器的底层处理方式。

像Java的web服务器,是多线程调用模型。每用户请求会打开一个线程,每个线程在内容中维护着用户的状态。

像PHP的web服务器,是交行CGI的程序处理,CGI是无状态的,所以一般用cookie在客户的浏览器是维护用户的状态。但cookie在客户端维护的信息是不够的,所以CGI应用要模仿用户session,就需要在服务器端生成一个session文件存储起来,让原本无状态的CGI应用,通过中间文件的方式,达到session的效果。

Nodejs的web服务器,也是CGI的程序无状态的,与PHP不同的地方在于,单线程应用,所有请求都是异步响应,通过callback方式返回数据。如果我们想保存session数据,也是需要找到一个存储,通过文件存储,redis,Mongdb都可以。

接下来,我将演示如何通过mongodb来保存session,并实现登陆后用户对象传递。

app.js文件

在相应位置添加下面代码:

var session = require('express-session');
var connect = require('connect');
var SessionStore = require("session-mongoose")(connect);
var store = new SessionStore({
url:"mongodb://localhost/session",
 interval: 120000
});
app.use(session({
 secret: 'test.com',
 store: store,
 cookie:{maxAge:10000} //expire session in 10 seconds
}));
//用于把登录用户设置到res.locals里面,在home.html里显示
app.use(function(req,res,next){
 res.locals.user = req.session.user;
 console.log('Session is = ',req.session.user);
 next();
});
로그인 후 복사

需要添加中间件connect、session-mongoose。

其中session-mongoose是用于连接mongodb数据库。然后自动写入session信息到数据库中(也可以用mongoose中间件,但是要自己实现session的写入)

app.use(session(….)) 这里是全局设置了session的信息及session信息存储的方式。

注:app.js文件有顺序要求,一定要注意!!!

安装session-mongoose依赖库

npm install connect

npm install session-mongoose

npm install session-mongoose

安装有错误但是没关系。

访问:http://localhost:3000/login,正常

修改routes/index.js文件

exports.doLogin方法

exports.doLogin = function(req, res){
 var user={ username:'admin', password:'admin' } 
 if(req.body.username===user.username && req.body.password===user.password){ 
  req.session.user=user; 
  return res.redirect('/home');
 } else { 
  return res.redirect('/login'); 
 }
};
로그인 후 복사

exports.logout方法

exports.logout = function(req, res){
 req.session.user=null;
 res.redirect('/');
};
로그인 후 복사

exports.home方法

exports.home = function(req, res){
 res.render('home', { title: 'Home'});
};
로그인 후 복사

这个时候session已经起作用了,exports.home的user显示传值已经被去掉了。 是通过app.js中app.use的res.locals变量,通过框架进行的赋值。

app.use(function(req, res, next){
 res.locals.user = req.session.user;
 next();
});
로그인 후 복사

注:这个session是express4.10.4的写法,与express4之前的版本是不一样的。

访问页面可以查看mongodb有没有数据:

nodejs-mongodb
nodejs-mongodb

由于上面配置的 cookie:{maxAge:10000} //expire session in 10 seconds
过期时间,因此你会看到mongodb里面的数据过一段时间就被清除了。
参考:

Mongoose:http://mongoosejs.com/

关于express4.2.0与express3.x操作的区别:http://blog.csdn.net/u013758116/article/details/38758351

8. 页面提示

登陆的大体我们都已经讲完了,最后看一下登陆失败的情况。

我们希望如果用户登陆时,用户名或者密码出错了,会给用户提示,应该如何去实现。

打开app.js的,增加res.locals.message

登陆的大体我们都已经讲完了,最后看一下登陆失败的情况。

我们希望如果用户登陆时,用户名或者密码出错了,会给用户提示,应该如何去实现。

打开app.js的,增加res.locals.message

app.use(function(req, res, next){
 res.locals.user = req.session.user;
 var err = req.session.error;
 delete req.session.error;
 res.locals.message = '';
 if (err) res.locals.message = '<div class="alert alert-danger">' + err + '</div>';
 next();
});
로그인 후 복사

修改login.html页面,<%- message %>

<% include header.html %>
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<%- message %>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username" value="admin">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password" value="admin">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>
로그인 후 복사

修改routes/index.js,增加req.session.error

exports.doLogin = function(req, res){
 var user={
 username:'admin',
 password:'admin'
 }
 if(req.body.username===user.username && req.body.password===user.password){
 req.session.user=user;
 return res.redirect('/home');
 } else {
 req.session.error='用户名或密码不正确';
 return res.redirect('/login');
 }
};
로그인 후 복사

让我们来看看效果: http://localhost:3000/login 输入错误的和密码, 用户名:dad,密码:da

boostrap-nodejs

9. 页面访问控制

网站登陆部分按照我们的求已经完成了,但网站并不安全。

localhost:3000/home,页面本来是登陆以后才访问的,现在我们不要登陆,直接在浏览器输入也可访问。

页面报错了,提示<%= user.username %> 变量出错。

GET /home?user==a 500 15ms
TypeError: D:\workspace\project\nodejs-demo\views\home.html:2
1| <% include header.html %>
>> 2|

Welcome <%= user.username %>, 欢迎登陆!!


3| http://www.geedoo.info/logout">退出
4| <% include header.html %>
Cannot read property 'username' of null
at eval (eval at (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at eval (eval at (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:249:15
at Object.exports.render (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:287:
at View.exports.renderFile [as engine] (D:\workspace\project\nodejs-demo\node_modules\ejs\l
at View.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\view.js:75:8)
at Function.app.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\applicati
at ServerResponse.res.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\res
at exports.home (D:\workspace\project\nodejs-demo\routes\index.js:36:8)
at callbacks (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:161

这个页面被打开发,因为没有user.username参数。我们避免这样的错误发生。

还记录路由部分里说的get,post,all的作用吗?我现在要回到路由配置中,再做点事情。

修改app.js文件

app.get('/',routes.index);
app.route('/login')
.all(notAuthentication)
.get(routes.login)
.post(routes.doLogin);
app.route('/logout')
app.get('/',routes.index);
app.route('/login')
.all(notAuthentication)
.get(routes.login)
.post(routes.doLogin);
app.route('/logout')
.get(authentication)
.get(routes.logout);
app.route('/home')
.get(authentication)
.get(routes.home);

访问控制:

/ ,谁访问都行,没有任何控制
/login,用all拦截所有访问/login的请求,先调用authentication,用户登陆检查
/logout,用get拦截访问/login的请求,先调用notAuthentication,用户不登陆检查
/home,用get拦截访问/home的请求,先调用Authentication,用户登陆检查
修改app.js文件,增加authentication,notAuthentication两个方法

function authentication(req, res, next) {
 if (!req.session.user) {
 req.session.error='请先登陆';
 return res.redirect('/login');
 }
 next();
}
function notAuthentication(req, res, next) {
 if (req.session.user) {
  req.session.error='已登陆';
  return res.redirect('/home');
 }
 next();
}

로그인 후 복사

配置好后,我们未登陆,直接访问localhost:3000/home时或者localhost:3000/logout,就会跳到/login页面

登录后, 访问localhost:3000/login 则直接跳到/home页面

到此,express4 相关内容到此为止。

以上内容是小编给大家分享的Nodejs Express4.x开发框架随手笔记,希望大家喜欢。

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿