學習NodeJS也有一兩個星期了,感覺進度很慢,估計是自己智商跟不上同時也很不習慣js語言,不過爲了畢設也是豁出去了。這裏就用Nodejs+Mongodb寫一個註冊與登入案例,全當學習,高手繞過。
首先明確功能:1、登入;2、註冊,3、顯示登入信息。這是一個最簡單的功能。接下下來開始編寫。默認大家都安裝好了工具(WebStorm+Mongodb)。
1、建立工程MongodbTest,在工程下建立一個package.json依賴表。將所需要的模板添加進去。
package.json.
<span style="font-size:18px;">{
"name": "mongodbtest",
"version": "0.0.1",
"author":"xxk",
"dependencies": {
"express": "3.2.2",
"ejs": "*"
}
}</span>
然後再cmd下進入該工程執行 npm install將所要的模塊安裝進去,npm如依據package.json中的dependencies下定義的模塊依次安裝。
2、安裝成功後,在工程中會多了一個文件夾node_modules。安裝的模塊就在這個文件夾下。下面在該工程中新建一個app.js。將需要的模塊引進去require(''); app.js是工程的一個入口
3、首先配置Express
<span style="font-size:18px;">/**
* modules dependencies
* @type {exports}
* 模板依賴
*/
var express = require('express');
var routes = require('./routes');
var http = require('http');
var ejs = require('ejs');
var path =require('path');
var SessionStore=require('session-mongoose')(express);
var store=new SessionStore({
url:"mongodb://localhost/session",
interval: 120000 // expiration check worker run interval in millisec (default: 60000)
});
var app = express();
//all environment
app.set('port',process.env.port||3000);//set port
app.set('view',__dirname+'views');
app.engine('.html',ejs.__express);
app.set("view engine",'html'); //解析的模板是html
//添加中間件
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.cookieSession({secret : 'blog.fens.me'}));
app.use(express.session({
secret : 'blog.fens.me',
store: store,
cookie: { maxAge: 900000 } // expire session in 15 min or 900 seconds
}));
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-error">' + err + '</div>';
}
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname,'public')));
//development only
if('development'==app.get('evn')){
app.use(express.errorHandler());
}
</span>
首先我們導入Express模塊,routes是一個本地文件夾模塊,即./routes/index.js,它的功能是爲指定路徑組織返回內容相當於MVC框架中的控制器。通過express()創建了一個應用實例,後面的所有操作都是針對這個實例進行的。下面的app.set()是Express設置參數的工具,接受一個鍵(key)和一個值(value),可用的參數如下:
1、basepatn:基礎地址,通常用於res.redirect()跳轉。
2、views:視圖文件的目錄,存放文檔文件。
3、view engine:視圖模板引擎
4、view options:全局視圖對象
5、view cache:全局視圖緩存
6、case sensitive routes:路徑區分大小寫
7、strict routing:嚴格路徑,啓用後會忽略路徑末尾的"/"。
8、jsonp callback:開啓透明的JSONP支持。
Express依賴於connect提供了大量的中間件,可以通過app.use啓用,以上啓用的中間件功能爲。
1、bodyParse:解析客戶端請求,通常是通過post發送內容。
2、methodOverride:用於支持定製的HTTP方法。
3、router:項目的路由支持
4、static:提供靜態文件支持
5、errorHandler:錯誤控制器。
<span style="font-size:18px;">//basic
app.get('/',routes.index);</span>
app.get('/',routes.index),是一個路由控制器,用戶如果訪問“/”,路徑則由routes.index來控制。<span style="font-size:18px;">http.createServer(app).listen(app.get('port'),function(){
console.log("Express server listening on port"+app.get('port'));
});</span>
最後服務器通過http.createServer().listen(app.get('port'))啓動,監聽3000端口
4、routes/index.js
routes/index.js是路由文件,相當於控制器,用於組織展示控制界面。
<span style="font-size:18px;">exports.index = function(req, res){
console.log('xx');
res.render('index', { title: 'Index' });
};
exports.login=function(req,res){
res.render('login',{title:'用戶登錄'});
};</span>
app.js中通過app.get('/',routes.index);將"/"路徑映射到exports.index函數。其中只有一句res.render('index',{title:'Index'})
,功能是調用模板解析引擎,翻譯名爲index模板,並傳入一個對象作爲參數,這個對象只有一個屬性,即title:"Index"。
完整源碼:
app.js
<span style="font-size:18px;">/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, movie = require('./routes/movie')
, http = require('http')
, path = require('path')
, ejs = require('ejs')
, SessionStore = require("session-mongoose")(express);
var store = new SessionStore({
url: "mongodb://localhost/session",
interval: 120000 // expiration check worker run interval in millisec (default: 60000)
});
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('.html', ejs.__express);
app.set('view engine', 'html');// app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.cookieSession({secret : 'blog.fens.me'}));
app.use(express.session({
secret : 'blog.fens.me',
store: store,
cookie: { maxAge: 900000 } // expire session in 15 min or 900 seconds
}));
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-error">' + err + '</div>';
next();
});
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
//basic
app.get('/', routes.index);
app.all('/login',notAuthentication);
app.get('/login',routes.login);
app.post('/login',routes.doLogin);
app.get('/logout',authentication);
app.get('/logout',routes.logout);
app.get('/home',authentication);
app.get('/home',routes.home);
http.createServer(app).listen(app.get('port'),function(){
console.log("Express server listening on port"+app.get('port'));
});
function notAuthentication(req,res,next){
if(req.session.user){
console.log("xx="+req.session.user)
req.session.error='已登錄';
return res.redirect('/home');
}
next();
};
function authentication(req,res,next){
if(!req.session.user){
console.log(req.session.user);
req.session.error="請先登錄";
return res.redirect('/login');
}
next();
}
</span>
routes/index.js
<span style="font-size:18px;">/**
* Created by kevin on 2015/1/14.
*/
exports.index = function(req, res){
console.log('xx');
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){
req.session.user=user;
return res.redirect('/home');
}else{
req.session.error="用戶名或密碼不正確";
return res.redirect('/login');
}
};
exports.logout=function(req,res){
req.session.user=null;
res.redirect('/');
}
exports.home=function(req,res){
res.render('home',{title:'home'});
};</span>
views/index.html
<span style="font-size:18px;"><% include header.html %>
<h1>Welcome to <%= title %></h1>
<p><a href="/login">登陸</a></p>
<% include footer.html %></span>
views/header.html
<span style="font-size:18px;"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%=: title %></title>
<!-- Bootstrap -->
<link href="/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen">
<!-- <link href="css/bootstrap-responsive.min.css" rel="stylesheet" media="screen"> -->
</head>
<body screen_capture_injected="true"></span>
views/footer.html
<span style="font-size:18px;"><script src="/javascripts/jquery-1.9.1.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
<script src="/javascripts/movie.js"></script>
<script src="/javascripts/jquery.json-2.4.js"></script>
</body>
</html></span>
views/home.html
<span style="font-size:18px;"><% include header.html %>
<h1>Welcome <%= user.username %>, 歡迎登陸!!</h1>
<a claa="btn" href="/logout">退出</a>
<% include footer.html %></span>
views/login.html<span style="font-size:18px;"><% 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="text" 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 %>
</span>