前言:
express作為一個Node框架,很適合新學習Node的同學,加上mongoose的數據處理,堪稱完美~ 閑話少說,步入正題。
我的系統環境:
1. 建立項目
Node及express的安裝這里就不再贅述,網上有很多安裝的教程,不會的同學可以自行查找,這里我們采用express4.x版本
安裝express庫完成之后,我們可以使用express命令來建立一個自己的項目: express -e vlan
可以看到express幫我們創建了一個完整的項目級目錄
express默認的是jade的模版, -e代表使用ejs, 這里我們使用ejs
接下來進入項目目錄並安裝express所需的依賴
2.目錄結構
www文件就是啟動文件
node_modules 存放所有項目的依賴
public為靜態資源存放目錄,可以修改
routes為路由文件
views就是視圖了(頁面文件,ejs模板)
3. app.js核心文件
一般可能會改動的地方我都注釋了出來, 完整的app.js文件如下
var express = require('express'); var path = require('path'); var favicon = require('serve-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); //var users = require('./routes/users'); var ejs = require("ejs"); var app = express(); // 視圖目錄 app.set('views', path.join(__dirname, 'views')); // 使用ejs模板 (替換為html文件) app.engine('.html', ejs.__express); app.set('view engine', 'html'); //app.set('view engine', 'ejs'); // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); // 靜態資源存放目錄 app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); //app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
查看./bin/www文件。
#!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('vlan:server'); var http = require('http'); /** * Get port from environment and store in Express. */ /* * 定義啟動端口 * */ var port = normalizePort(process.env.PORT || '8080'); app.set('port', port); /** * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); }
4.路由功能
首先在項目目錄里創建一個controller即控制層
在controller下新建index.js 這里面我們簡單的返回一個title來進行測試
exports.index = function (){ return {title: "歡迎來到我的首頁!"}; };
接下來我們在路由層里面設置index.js
var express = require('express'); var router = express.Router(); // 引入c層的各個控制器 var indexController = require("../controller/index"); /* GET index page. */ router.get('/index', function(req, res, next) { res.render('index', indexController.index()); }); module.exports = router;
然后對V層的index.html模板進行修改
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/css/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> </body> </html>
這里我們采用的是ejs模板,所以要嚴格按照ejs的模板規則,當然也可以用其他模版引擎,比如jade等等
另外我對靜態資源目錄進行了一些小修改,主要是個人習慣,
原本的靜態資源目錄:
改過后的靜態資源目錄:
所以頁面引用的時候要稍微注意下,當資源加載的時候,默認從public下查找,所以引用的路徑:<link rel='stylesheet' href='/css/style.css' />
一切大功告成,接下來我們可以啟動服務,來訪問我們的測試頁面,終端可以用npm start進行訪問,我用的webstorm直接debug就可以看到效果
可以看到我們可以成功訪問頁面,並且css也成功加載。
到這為止,其實一個簡單的express的搭建就已經完成,感覺很簡單,對不對? 只要整站的架構思維理順,一切都能迎刃而解!
5.完整的項目
接下來我們做一個簡單的登錄注冊,使用MongoDB做為我們的數據庫。
做之前我們先來規划一下思路:
①新建兩個頁面,一個登錄頁(login.html), 登錄成功后的跳轉頁(home.html)
②照葫蘆畫瓢,按照剛剛的順序,先跑通這兩個頁面
③寫登錄和注冊的接口,這個時候我們就需要用到數據庫了,注冊之前先進行查詢,數據庫里是否有這個用戶名,然后是登錄,賬戶與密碼是否匹配
④前端的注冊和登錄的功能實現
大體上就這個思路,讓我們來一步步進行。
1.創建登錄頁以及登錄成功頁
在路由層的index.js里面新增代碼:
var loginController = require("../controller/login"); /* GET login page. */ router.get('/login', function(req, res, next) { res.render('login', loginController.login()); });
C層的login.js:
exports.login = function (){ return {title: "這里是登錄頁"}; };
V層的login.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title><%=title%></title> <script></script> <link rel="stylesheet" href="/css/login.css"/> </head> <body> <h1>~<%=title%>~</h1> <form id="myForm"> 帳號:<input type="text" name="username"/><br/><br/> 密碼:<input type="password" name="password"/><br/><br/> <input type="button" value="注冊" node-type="register" /> <input type="button" value="登錄" node-type="submit"/> </form> <script src="/js/jquery.js"></script> <script src="/js/login.js"></script> </body> </html>
樣式簡單的寫寫就可以啦~
重啟服務,訪問login:
全部OK,接下來是home頁面,由於home頁是登陸成功頁,所以我們做個假的帳號進行測試:
路由層的index.js添加訪問home的方法:
/* GET home page. */ router.get('/home', function(req, res, next) { res.render('home', { title: "登錄成功頁", username: "測試帳號" }); });
V層的home.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>恭喜~<%= title %>~恭喜</title> <link rel="stylesheet" href="/css/home.css"/> </head> <body> <h1>尊敬的<%= username %>,歡迎您!</h1> <a class="logout" href="/logout">退出登錄</a> </body> </html>
同樣樣式簡單寫寫就可以了
重啟服務,訪問home頁:
可以看到訪問成功,這里其實我們應該有一個退出登錄的頁面,我就不再單寫一個頁面了,退出登陸后直接跳轉到登錄頁就可以了~~~
路由層曾加一個訪問logout的方法就可以:
/*GET logout page.*/ router.get('/logout', function (req, res){ res.redirect("/login"); });
重啟服務后我們點退出登錄按鈕,可以看到直接跳轉到了登錄頁~
好了,接下來該實現前端登錄注冊的功能了,這里先來寫登錄的功能,我們先來規定下接口的格式:{“code”: 200, “msg”: “登錄成功”}
code等於200的時候,為登錄成功,201為登錄失敗。我們先用get方式來測試頁面,跑通頁面以后再用post方式提交
在C層新建getLogin.js:
var userList = {}; exports.getLogin = function (req, res){ res.send({ code:200, msg: "登錄成功(本條消息來自后台)" }); userList = { username: req.param("username") } }; exports.userList = function (){ return userList; };
userList用來存儲登錄時所填寫的用戶信息(可以理解成一個數據庫,從數據庫里讀取內容)
在路由層的index.js做如下改動:
var getLoginController = require("../controller/getLogin"); /* GET home page. */ router.get('/home', function (req, res){ res.render('home', { title: "登錄成功頁", username: getLoginController.userList().username }); }); router.get('/userData', getLoginController.getLogin);
userData即前端的接口地址
現在就可以來寫寫前端登錄的功能了:
;(function ($){ var foo = function (options){ var self = this; self.options = $.extend({ parent: $("#myForm"), register: $("[node-type=register]"), submit: $("[node-type=submit]") }, options); self.bindEvent(); }; foo.prototype = { bindEvent: function (){ var self = this; self.login(); }, login: function (){ var self = this, parent = self.options.parent, submit = self.options.submit; submit.on("click", function (){ var jqXML = $.ajax({ url: "/userData", dataType: "json", type: "get", data: parent.serialize() }); jqXML.done(function (data){ if(data.code == 200){ location.href = "/home"; } }); }); } }; new foo(); })(jQuery);
簡單的get提交方式,記得在login.html頁面上引用~
一切OK,重啟服務,訪問login頁面
輸入用戶名以后點擊登錄:
恭喜!訪問成功!
下一節我們將跟數據庫連接起來,做一個真正意義上的登錄注冊。