- 简
Nodejs给Javascript赋予了服务端应用的生命,Jquery让Javascript成为浏览中开发的利器。 最近学习了Nodejs的Express4.0的开发框架,浏览网上各种资料,由于版本原因自己模索中还是走了不少弯路的。写篇文章总结一下
转载请注明出处:
程序代码已经上传到github有需要的同学,自行下载。
https://github.com/xyl1993/nodeDemo
目录
1、建立工程
2、目录结构
3、app.js核心文件
4、Bootstrap界面框架
5、路由功能
6、Angularjs界面框架
7、程序代码
1、建立项目
准备工作:安装nodejs程序
1、全局安装express npm install -g express
安装完nodejs再全局安装express时成功后,输入express指令会提示'express' 不是内部或外部命令,也不是可运行的程序或批处理文件
此时可用npm install -g express-generator解决这个问题
安装完成后查看版本号
接下来我们使用express命令创建项目了
express -e nodeDemo #创建项目
cd nodeDemonpm install #依赖包安装
npm start #启动项目
2、目录结构
bin, 存放启动项目的脚本文件
bower_components,通过bower安装的第三方包
node_modules, 存放所有的项目依赖库
conf,mysql配置文件
dao,数据操作文件
public,静态文件(css,js,img)
routes,路由文件(MVC中的C,controller)
views,页面文件(Ejs模板,html页面)
package.json,项目依赖配置及开发者信息
app.js,应用核心配置文件
my_log4js.json,log4j配置文件
3、app核心配置
app.js:
//加载依赖库 加载之前需要通过npm进行安装
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser'); //cookie
var bodyParser = require('body-parser');
//加载路由配置
var routes = require('./routes/index');
var users = require('./routes/users');
var ejs = require('ejs');
var session = require('express-session'); //session
var redisStore = require('connect-redis')(session);
var flash = require('connect-flash');
var log4js = require('log4js'); //log4j
var mysql = require('mysql'); //mysql
var app = express();
//log4js
log4js.configure('my_log4js_configuration.json',{}); //加载log4j配置文件
var logger = log4js.getLogger('nomel');
logger.setLevel('INFO');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
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(log4js.connectLogger(logger, {level: 'auto', format:':method :url'}));
app.use(session({
secret:'recommand 128 bytes random string',
cookie: {maxAge:60 * 1000}
}));
//定义静态文件路径
//这边一定要配置,否则加载静态资源时报404错误
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'bower_components')));
app.use(flash());
//定义模块引擎和模板文件位置,这边默认的是ejs,我 改为了html
app.engine('.html', ejs.__express);
app.set('view engine', 'html');// app.set('view engine', 'ejs');
//路由加载控制,根目录加载route,users目录加载users,在上方配置路径
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: {}
});
});
app.use(session({
// 假如你不想使用 redis 而想要使用 memcached 的话,代码改动也不会超过 5 行。
// 这些 store 都遵循着统一的接口,凡是实现了那些接口的库,都可以作为 session 的 store 使用,比如都需要实现 .get(keyString) 和 .set(keyString, value) 方法。
// 编写自己的 store 也很简单
store: new redisStore(),
secret: 'somesecrettoken'
}));
exports.logger=function(name){
var logger = log4js.getLogger(name);
logger.setLevel('INFO');
return logger;
};
module.exports = app;
4、Bootstrap界面框架
创建Bootstrap界面框架,直接在index.ejs文件上面做修改。可以手动下载Bootstrap库放到项目中对应的位置引用,也可以通过bower来管理前端的Javascript库,参考文章 bower解决js的依赖管理。另外还可以直接使用免费的CDN源加载Bootstrap的css和js文件。下面我就直接使用Bootcss社区提供的CDN源加载Bootstrap。
详细用法见bootstrap帮助文档:http://v3.bootcss.com/
这边要注意:放bootstrap的静态目录要在app中进行配置
5、路由功能
以我的路由配置为例:
var express = require('express');
var userDao = require('../dao/userDao'); //加载数据控制层
var router = express.Router();
var log = require('log4js').getLogger("index"); //加载log4j
/*以下是路由配置*/
/* GET home page. */
router.get('/', function(req, res, next) {
posts = [];
// res.render('index',{
// title:'首页',
// posts:posts,
// user: req.session.user,
// success : req.flash('success').toString(),
// error : req.flash('error').toString()
// })
res.render('main/index');
});
// router.get('/login',checkNotLogin); //通过公共方法判断用户是否登录
router.get('/login',function(req,res,next){
console.log("app.usr local");
res.locals.message = '';
var err = req.session.error;
delete req.session.error;
if (err) res.locals.message = '' + err + '';
res.render('login/login');
});
router.get('/found',function(req,res,next){
res.render('found/found');
});
router.get('/guangzhu',function(req,res,next){
res.render('guangzhu/guanzhu');
});
router.get('/register',function(req,res,next){
res.render('register',{title:'用户注册'});
});
router.get('/home',function(req,res,next){
console.log('ok');
var user = {
username : 'admin',
password : 'admin'
}
res.locals.user = req.session.user;
log.debug(res.locals.user);
res.redirect('/');
});
router.get("/logout", checkLogin);
router.get('/logout',function(req,res,next){
req.session.user=null;
req.flash('success', '退出成功');
res.redirect('/');
});
/*路由配置end*/
//请求配置
router.post('/login',checkNotLogin);
router.post('/login',function(req,res,next){
userDao.queryById(req, res, next);
});
router.post('/register',function(req,res,next){
userDao.add(req, res, next);
});
// 检查用户登录状态
function checkNotLogin(req,res,next){
if(req.session.user){
req.flash('error','用户已经登录');
return res.redirect('/');
}
next();
}
function checkLogin(req,res,next){
log.debug(req.session.user);
if(!req.session.user){
console.log(req.session.user);
req.flash('error','用户未登录');
return res.redirect('/login');
}
next();
}
module.exports = router;
usersDao文件:
// dao/userDao.js
// 实现与MySQL交互
var mysql = require('mysql');
var $conf = require('../conf/db'); //加载配置项
var $util = require('../util/util');
var $sql = require('./userSqlMapping'); //加载mapping文件
var log = require('log4js').getLogger("userDao");
// 使用连接池,提升性能
var pool = mysql.createPool($conf.mysql);
// 向前台返回JSON方法的简单封装
var jsonWrite = function (res, ret) {
if(typeof ret === 'undefined') {
res.json({
code:'1',
msg: '操作失败'
});
} else {
res.json(ret);
}
};
module.exports = {
add: function (req, res, next) {
pool.getConnection(function(err, connection) {
// 获取前台页面传过来的参数
var param = req.query || req.params;
// 建立连接,向表中插入值
// 'INSERT INTO user(id, name, age) VALUES(0,?,?)',
connection.query($sql.insert, [req.body.username, req.body.password], function(err, result) {
log.debug(result);
if(result) {
// result = {
// code: 200,
// msg:'增加成功'
// };
res.redirect('/login');
}
// 以json形式,把操作结果返回给前台页面
// jsonWrite(res, result);
// 释放连接
connection.release();
});
});
},
delete: function (req, res, next) {
// delete by Id
pool.getConnection(function(err, connection) {
var id = +req.query.id;
connection.query($sql.delete, id, function(err, result) {
if(result.affectedRows > 0) {
result = {
code: 200,
msg:'删除成功'
};
} else {
result = void 0;
}
jsonWrite(res, result);
connection.release();
});
});
},
update: function (req, res, next) {
// update by id
// 为了简单,要求同时传name和age两个参数
var param = req.body;
if(param.name == null || param.age == null || param.id == null) {
jsonWrite(res, undefined);
return;
}
pool.getConnection(function(err, connection) {
connection.query($sql.update, [param.name, param.age, +param.id], function(err, result) {
// 使用页面进行跳转提示
if(result.affectedRows > 0) {
res.render('suc', {
result: result
}); // 第二个参数可以直接在jade中使用
} else {
res.render('fail', {
result: result
});
}
connection.release();
});
});
},
queryById: function (req, res, next) {
// var id = +req.query.id; // 为了拼凑正确的sql语句,这里要转下整数
pool.getConnection(function(err, connection) {
connection.query($sql.queryByNameAndPwd, [req.body.user, req.body.password], function(err, rows,result) {
log.debug(rows);
var resMap = {};
var id = rows[0].id+'';
// jsonWrite(res, result);
if(id){
connection.query($sql.queryById,id,function(err,result){
log.debug(result);
var user={
username : result[0].name
};
req.session.user = user;
log.debug(req.session.user);
resMap.code=0;
resMap.data=result[0];
res.send(resMap);
})
}else{
req.session.error = '用户名密码不正确';
return res.redirect('/login');
}
connection.release();
// return result;
});
});
},
queryAll: function (req, res, next) {
pool.getConnection(function(err, connection) {
connection.query($sql.queryAll, function(err, result) {
jsonWrite(res, result);
connection.release();
});
});
}
};
mapping文件:
var user = {
insert:'INSERT INTO t_user(name, password) VALUES(?,?)',
update:'update t_user set name=?, password=? where id=?',
delete: 'delete from t_user where id=?',
queryById: 'select * from t_user where id=?',
queryByNameAndPwd:'select id from t_user where name=? and password=?',
queryAll: 'select * from t_user'
};
module.exports = user;
6、Angularjs
AngularJS是开发基于浏览器的响应式RWD应用程序的一个前端MVC框架,由谷歌最初开发的 开源项目,干净的架构吸引了大量粉丝,适合建立CRUD类型的业务应用程序,并不适合开发游戏等应用, 使用声明性编程的用户界面和命令式编程的逻辑, 支持现代桌面和移动浏览器 Internet Explorer版本8.0及以上。不得不说使用angularjs开发web项目真是爽
这边只介绍基础配置
以下为html实例代码
首页
-
简
-
-
-
-
- 发现
- 光注
//ui-view视图加载核心指令
//引入angularjs
//ui-route路由
main.js
var mainModule = angular.module('main', ['ui.router',
//全局配置 'ngResource', 'ngSanitize','w5c.validator']);
mainModule.run(function($rootScope, $state, $http, $stateParams, $location,$timeout,$window) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
})
//路由配置
mainModule.config(['$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider) {
$stateProvider.state('found',{
url : '/found', //注意这边的url路径要在路由里面进行get配置
templateUrl : '../found'
}).state('guanzhu',{
url : '/guanzhu', //发现
templateUrl : '../guangzhu'
})
}])
//控制器
mainModule.controller('testController', ['$scope', function($scope){
}])
$(function(){
$('#logIn').click(function(event) {
/* Act on the event */
var data={
'user' : $('#userName').val(),
'password' : $('#password').val()
};
$.ajax({
method : 'post',
url : '/login',
data:data
}).success(function(resp){
console.log(resp.code);
var data = resp.data;
console.log(data.name);
if(resp.code===0){
window.location.href="../home";
}
}).error(function() {
/* Act on the event */
console.log('aa');
});
});
})
7、程序代码
这个项目托管在github上,地址为:https://github.com/xyl1993/nodeDemo
在里面readme.md中写了启动方法
我的个人博客,https://nodeblog-xylblog.rhcloud.com/