Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/MonkSoul/Monk.Node
基于 Node.JS 一套 Web MVC 应用解决方案。
https://github.com/MonkSoul/Monk.Node
Last synced: 3 months ago
JSON representation
基于 Node.JS 一套 Web MVC 应用解决方案。
- Host: GitHub
- URL: https://github.com/MonkSoul/Monk.Node
- Owner: MonkSoul
- License: mit
- Created: 2016-12-13T04:35:51.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2021-12-08T09:23:53.000Z (almost 3 years ago)
- Last Synced: 2024-06-20T20:55:17.329Z (5 months ago)
- Language: JavaScript
- Homepage:
- Size: 230 KB
- Stars: 46
- Watchers: 12
- Forks: 15
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-github-star - Monk.Node
README
# Monk.Node — 极易入门的Node.JS MVC 框架
Monk.Node 是一个免费开源的,快速、简单的面向对象的轻量级Node.JS开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。Monk.Node从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。遵循MIT开源许可协议发布,意味着你可以免费使用Monk.Node,甚至允许把你基于Monk.Node开发的应用开源或商业产品发布/销售。
> Monk.Node 2.x 版本是一个颠覆和重构版本,采用全新的架构思想,引入了更多的Node.JS新特性,优化了核心,减少了依赖,实现了真正的惰性加载,支持npm,并针对Web开发做了大量的优化,包括路由、日志、异常、模型、数据库、模板引擎和验证等模块都已经重构,但绝对是新项目的首选(无论是WEB还是API开发)。
## 主要特性
- 目录规范,代码清晰,极易入门
- 基于 Node.JS 平台构建,Javascript 作为主要开发语言
- 底层以 [Express.js](http://www.expressjs.com.cn/) 为基石,拓展性强,组件丰富
- 采用主流的 MVC 思想编写,前后端解耦
- 内置 Node.JS 平台下强大的 ORM 组件:[Sequelize.js](http://docs.sequelizejs.com/en/v3/),支持目前主流的数据库操作
- 集成 Web 开发所需的基本组件,无需手工添加
- 支持 WebSocket 开发
- 支持 RESTful API 开发
- 支持 Redis 存储
- 支持 Cors 跨域
- 支持数据库模型自动构建
- 支持有效防止 CSURF 攻击
- 支持邮件发送
- 支持定时任务
- 支持验证码生成Monk.Node 目前还在持续新增更多新特性,新功能,更多特性可持续关注项目更新。
> Monk.Node 基于 Express.js 开发,但更优于 Express.js 本身提供的脚手架!—— 伟大的项目都是站在巨人的肩膀上的 * _* !
## 作者信息
- 原创作者:百小僧
- 开源协议:MIT License
- 开发时间:2016年12月06日
- 当前版本:`2.2.9`,2017年02月06日
- 项目名称:Monk.Node
- 开发理念:一切从简,只为了更懒
- 码云地址:http://git.oschina.net/baisoft_org/Monk.Node
- Github :https://github.com/MonkSoul/Monk.Node## 视频教程
1. [Monk.Node 简介&安装](http://url.cn/42W06hK)
2. [Monk.Node 控制器](http://url.cn/42W06hK)
3. [Monk.Node 视图引擎](http://url.cn/42W06hK)
4. [Monk.Node 区域](http://url.cn/42W06hK)
5. [Monk.Node 静态资源](http://url.cn/42W06hK) **(项目已调整,请按照最新文档)**
6. [Monk.Node 模型](http://url.cn/42W06hK)
7. [Monk.Node ORM](http://url.cn/42W06hK)
8. [Monk.Node 会话](http://url.cn/42W06hK)
9. [Monk.Node 过滤器](http://url.cn/42W06hK)
10. [Monk.Node 文件上传](http://url.cn/42W06hK)
11. Monk.Node Redis(未更新)
12. Monk.Node WebSocket(未更新)
13. Monk.Node 入口文件(未更新)
14. Monk.Node RESTful(未更新)
## 更新记录
```
============ 2017.02.06 V2.2.9 ============
- [新增] log4js 日志访问组件
- [新增] config/log4js.json 日志配置文件
- [新增] utils/log4js.js 日志记录工具类
- [修复] 记录日志时,logs文件夹不存在问题
- [更新] README.md 文档
- [更新] package.json依赖模块============ 2017.01.24 V2.2.8 ============
- [更新] README.md 文档
- [更新] package.json依赖模块============ 2017.01.12 V2.2.7 ============
- [更新] package.json依赖模块
============ 2016.12.23 V2.2.6 ============
- [更新] app.js 入口文件,将ejs模板引擎文件名改为.html(重点更新)
============ 2016.12.22 V2.2.5 ============
- [新增] locals文件夹,定义全局数据注入,类似ASP.NET MVC的ViewData数据
- [新增] utils/locals.js 模块,全局注入核心模块
- [更新] app.js 核心代码,使其支持全局数据注入
- [更新] utils/route.js 模型,使其支持局部数据注入
- [更新] 使用文档
- [更新] sequelize模块
- [更新] debug模块
- [优化] utils/route.js代码
- [修复] 表单 enctype="multipart/form-data" 数据无法获取问题============ 2016.12.20 V2.2.3 ============
- [新增] utils/route.js 默认路由区域设置,默认控制器,默认Action路由支持
如:http://localhost:3000 == http://localhost:3000/frontend == http://localhost:3000/frontend/home == http://localhost:3000/frontend/home/index
- [更新] app.js 核心代码
- [更新] multer 文件上传模块
- [更新] debug 调试模块
- [优化] utils/route.js 核心代码
- [删除] app.js 默认首页设置代码,调整为默认区域设置,默认首页由 默认区域,默认控制器,默认Action组成
- [修复] utils/route.js 路由解析 由于node.js版本低导致路由解析报404错误
- [修复] 文档错误问题============ 2016.12.16 V2.2.1 ============
- [新增] 验证码模块,并编写验证码类库:utils/captcha.js
- [新增] 验证码演示示例,http://localhost:3000/backend/
- [删除] 删除所有区域下的assets资源文件
- [删除] core文件夹,并将db.js,route.js转移到utils目录下
- [更新] 错误提示页面,显示更多错误信息
- [更新] 设置根目录下的public为资源文件,保持和express.js兼容 (重要调整)
- [更新] core/db.js 加载模块代码,新增可配置的加载项
- [更新] 基本示例
- [更新] 静态资源文档============ 2016.12.15 V2.1.2 ============
- [新增] 数据库操作db全局对象,无需通过 require进来了(**重点更新**)
- [新增] utils/gmodels/js 模块
- [新增] 轻量级的images库,支持图片处理,包括水印,调整大小等等
- [新增] 定时任务node-schedule模块
- [新增] 邮件发送nodemailer模块
- [新增] lodash模块,提供非常方便的JavaScript工具操作库
- [新增] 视频教程
- [优化] 路由核心类库
- [更新] debug模块
- [更新] app.js 错误日志保存方法,以天为单位
- [更新] 默认示例
- [更新] ORM文档============ 2016.12.14 V2.1.1 ============
- [优化] 全面优化app.js 代码
- [新增] 全局路由过滤器
- [重构] 重构express.js单视图引擎,实现多视图引擎
- [更新] 目录结构,移除根目录下的assets,views文件夹,新增share文件夹
- [更新] postgres 版本
- [更新] socket.io 版本
- [更新] 使用文档
- [修复] Session和Cookie无作用bug
- [修复] core/db.js 加载模型错误============ 2016.12.13 V2.0.1 ============
- [新增] cors跨域支持
- [新增] 防止csurf攻击支持,提供更安全的开发环境
- [新增] typescript 支持,可以用typescript开发nodejs模块
- [新增] logs/access和logs/error 用于保存日志记录
- [新增] 写入访问日志功能
- [新增] 写入错误日志功能
- [新增] 日志切割功能
- [新增] 支持日志写入文件和写入数据库功能
- [新增] package.json模块依赖 file-stream-rotator
- [优化] app.js 入口文件,提高访问性能
- [更新] 控制台日志输出为combined,之前版本为dev
- [更新] 开发文档,新增防止CSURF攻击示例============ 2016.12.10 V2.0.0 ============
- [新增] app.js 入口文件默认应用首页设置
- [新增] 支持设置默认控制器,默认Action
- [新增] 区域目录,支持多站点项目开发,默认包含backend(后台),frontend(前台)两个区域
- [新增] core文件夹,将models/index.js模块移动到core/db.js模块
- [调整] public名称为assets,,默认包含backend(后台),frontend(前台),vendor(第三方插件)三个资源目录
- [调整] views视图子目录,默认包含backend(后台),frontend(前台)两个区域视图
- [调整] utils/socketServer.js名称为utils/socket.js
- [优化] app.js 代码,提高加载性能,只支持设置默认区域,默认控制器,默认Action
- [去除] express-controller模块,通过自定义实现更强大的功能============ 2016.12.08 V1.0.2 ============
- [新增] 即时通讯、聊天示例(推荐)
- [新增] socket.io 支持
- [新增] redis 支持
- [新增] multer 文件上传
- [新增] uploads 文件夹
- [优化] app.js 入口文件 端口和静态文件,用户上传文件代码
- [优化] 代码注释,代码架构
- [修复] package.json 中 mysql依赖包错误============ 2016.12.07 V1.0.1 ============
- [新增] 演示站点
- [新增] 默认控制器,默认控制器为Home,默认行为为Index
- [新增] model代码生成器
- [新增] package.json 依赖 sequelize-auto
- [优化] 目录解构
- [修复] app.js 入口文件bug============ 2016.12.06 V1.0.0 ============
- [发布] v1.0.0 版本
```
## 目录结构
初始化目录结构
```
www WEB部署目录
├─area 区域目录
│ ├─backend 后台区域目录
│ │ ├─controllers 后台控制器目录
│ │ │ ├─homeController.js 后台默认控制器
│ │ ├─views 后台视图目录
│ ├─frontend 前台区域目录
│ │ ├─controllers 前台控制器目录
│ │ │ ├─homeController.js 前台默认控制器
│ │ ├─views 前台视图目录
│ ├─tools 工具区域目录
│ │ ├─controllers 前台控制器目录
│ │ │ ├─generateController.js 数据库模型生成 控制器
│ │ ├─views 后台视图目录
├─config 配置目录
│ ├─db.json 数据库配置文件
├─filters 过滤器,中间件目录
├─locals 全局数据注入目录,支持.json文件和.js模块
├─logs 日志保存目录
│ ├─access 访问日志
│ ├─error 错误日志
├─models 数据库表对应模型目录
├─public 静态资源目录
│ ├─favicon.ico 网站收藏图标
├─uploads 用户上传文件存放目录
├─utils 工具类库目录
│ ├─socket.js Socket.io 服务器演示代码
│ ├─db.js 数据库模型操作核心库
│ ├─route.js 路由解析核心库
├─app.js 入口文件
├─package.json 包配置文件
```## 使用教程
### 安装
- `git` 方式
```
$ git clone https://git.oschina.net/baisoft_org/Monk.Node.git$ cd Monk.Node
$ npm install
$ npm start
浏览器:http://localhost:3000/
```- `zip` 下载
```
浏览器访问:http://git.oschina.net/baisoft_org/Monk.Node$ cd Monk.Node
$ npm install
$ npm start
浏览器:http://localhost:3000/
```### **全局数据注入(v2.2.5 支持)**
全局数据注入 表示可以在 `locals`目录下定义`.json`或者`.js`模块文件,这个文件中暴露的数据或者接口可以在 **整个请求,整个控制器,整个Action和整个视图模板(ejs)中使用**
例如:在locals文件夹下定义 `setting.js`模块文件
```
module.exports = {
"name": "Monk.Node",
"version": "2.2.5",
"author": "百小僧",
"company": "百签软件(中山)有限公司"
};
```- 在控制器中的使用:res.locals.文件名
```
module.exports={
get_index:function(req,res){
var setting=res.locals.setting; // setting就是文件名
var name= setting.name; // => Monk.Node
var version= setting.version; // => 2.2.5
}
};
```- 在视图页面ejs中使用 _locals.文件名
```
<%=_locals.setting.name %>
<%=_locals.setting.version %>
<%=_locals.setting.company %>
```当然,我们也可以定义局部数据注入,局部数据注入通常在`action`中定义的
```
module.exports={
get_index:function(req,res){
res.locals.abc="我是局部的。。。。。";
}
};
```- 在视图页面ejs中使用
```
<%=_locals.abc %>
```全局数据注入使用非常灵活,可以结合数据库操作,最终通过 `module.exports`返回`json对象`数据即可
### 入口配置
- 设置视图模板引擎
```
app.set('view engine', 'ejs');
```- 设置静态资源目录
```
app.use(express.static(path.join(__dirname, 'public')));
```- 设置Cookie,Session配置信息
```
// cookie处理
app.use(cookieParser());
// session处理
app.use(session({
secret: 'monknode',
cookie: { maxAge: 60000 },
resave: true,
saveUninitialized: true
}));
```- 设置默认区域,控制器,Action目录及路由
```
// 设置控制器文件夹并绑定到路由
resolve
.setRouteDirectory({
areaDirectory: __dirname + '/areas',
controllerDirname: 'controllers',
defautController: 'home',
defautAction: 'index'
})
.bind(router);
```- 设置404,500错误处理
```
// 错误处理
// 404处理
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// 错误或者服务器500异常处理
app.use(function (err, req, res, next) {
var error = (req.app.get('env') === 'development') ? err : {};
//写错误日志
var errorMes = '[' + Date() + ']' + req.url + '\n' + '[' + error.stack + ']' + '\n';
errorLogStream.write(errorMes);
var status = err.status || 500;
res.status(status);
res.send('' + status + ' ' + err.message + '\n' + errorMes + '');
});
```- 设置网站监听端口,默认是`3000`
```
app.set('port', process.env.PORT || 3000);
```- 设置WebSocket启动,并设置服务端处理逻辑
```
require(path.join(__dirname, 'utils', 'socket')).listen(server);
```### 区域
> 区域是对网站和代码进行高度组装,如前台,后台。目前区域只支持控制器逻辑的编写。
- 新增区域
只需要在 `areas`目录下创建一个文件夹即可,并在此文件夹下创建`controllers`目录。如:`areas/api/controllers`
默认已经包含`backend`(后台),`frontend`(前台)两个区域
- 访问区域,默认访问的是 `homeController`控制器中的`get_index` Action。
```
http://localhost:3000/backend/http://localhost:3000/frontend/
http://localhost:3000/api/
```### 控制器
> 控制器是整个框架能够在浏览器上正确访问的基础单元,可以说是灵魂。注:控制器中命名为`homeController`的控制器为默认控制器,该控制器中的`get_index`为默认Action,此控制器有且只能包含一个Action,也就是`get_index`
- 创建控制器,控制器文件命名必须以`Controller`结尾,如在`frontend`区域中添加`controllers/aboutController.js`
```
module.exports={};
```- 在控制器中创建Action,也就是路由,路由遵循 `method_action`格式。在`aboutController.js`中定义
```
module.exports={
// 访问地址:http://localhost:3000/frontend/about/
get_index:function(req,res){
res.send("ok");
},// 提交地址:http://localhost:3000/frontend/about/create
post_create:function(req,res){
res.send("ok");
},// 访问地址:http://localhost:3000/frontend/about/company/baisoft
get_company_baisoft:function(req,res){
res.send("ok");
},// 访问地址:http://localhost:3000/frontend/about/company/10
get_company_id:function(req,res,id){
res.send("ok")
},// 访问地址:http://localhost:3000/frontend/about/company/10/百小僧
get_company_id_name:function(req,res,id,name){
res.send("ok");
},// 访问地址:http://localhost:3000/frontend/about/百小僧/company
get_name_company:function(req,res,name){
res.send("ok");
},// 过滤器
get_admin:[function(req,res,next){
if(未登录){
res.redirect("登录页面");
}
else{
next();
}
},function(req,res){
res.send("ok");
}],// 多个过滤器
get_admin:[function(req,res,next){
console.log("日志记录");
next();
},function(req,res,next){
if(未登录){
res.redirect("登录页面");
}
else{
next();
}
},function(req,res){
res.send("ok");
}],
};
```### 视图模板引擎
> 视图模板引擎采用的是`ejs`模板引擎,默认视图目录为:区域下的`views`文件夹。[ejs详细文档](https://www.npmjs.com/package/ejs)
- 基础语法
```
<% if (user) { %>
<%= user.name %>
<% } %>
```- 在控制器中使用
```
module.exports={
get_index:function(req,res){
res.render("frontend/about/index");
},
get_about:function(req,res){
res.render("frontend/about/index",{
user:{
name:"百小僧"
}
});
}
};
```- 引入公共布局
```
<%- include("header") %><%- include("footer") %>
// 传递参数
<%- include("header",{
name:"百小僧"
}) %><%- include("footer",{
name:"百小僧"
}) %>
```### 静态资源
> 静态资源默认目录为根目录下的`public`目录
- 基础使用
```
```
### 模型
> 模型主要放在`models`文件夹
- 定义一个和数据库表对应的模型:`member.js`
```
module.exports = function(sequelize, DataTypes) {
return sequelize.define('member', {
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
}
}, {
tableName: 'member',
timestamps: false,
freezeTableName: true
});
};
```由于构建模型是非常耗时而且重复代码多,所以本框架提供了数据表模型生成工具,通过下面地址可以快速构建模型,无需手工操作
生成前需配置 `config/db.json`配置文件,通常只需配置数据库类型,数据库连接信息即可
```
http://localhost:3000/tools/generate/models
```### 数据库CURD
数据库操作集成强大的ORM框架:Sequelize.js,支持目前所有主流数据库,[详细文档](http://docs.sequelizejs.com/en/v3/)
- 数据库配置信息,配置文件在`config/db.json`下面
```
{
// 开发环境
"development": {
"username": "sa", // 数据库用户名
"password": "000000", // 数据库密码
"database": "monk_node", // 数据库名称
"host": "MONKSOUL", // 服务器主机地址
"dialect": "mssql", // 数据库类型('mysql'|'mariadb'|'sqlite'|'postgres'|'mssql')
"output": "../models", // 生成实体模型(models)存放的目录
"additional": { // 其他参数
"timestamps": false,
"freezeTableName": true
}
},
// 测试环境
"test": {
"username": "sa",
"password": "000000",
"database": "monk_node",
"host": "MONKSOUL",
"dialect": "mssql",
"output": "../models",
"additional": {
"timestamps": false,
"freezeTableName": true
}
},
// 生产环境
"production": {
"username": "sa",
"password": "000000",
"database": "monk_node",
"host": "MONKSOUL",
"dialect": "mssql",
"output": "../models",
"additional": {
"timestamps": false,
"freezeTableName": true
}
}
}
```- CURD
```
module.exports={
// 新增
post_create:function(req,res){
db.member.create({name:"百小僧"}).then(function(msg){
// 新增成功
console.log(msg);
});
},
// 删除操作
post_delete:function(req,res){
db.member.destroy().then(function(msg){
// 删除成功
console.log(msg);
});
},
// 根据条件删除
post_delete:function(req,res){
db.member.destroy({
where:{
id:10
}
}).then(function(msg){
// 删除成功
console.log(msg);
});
},
// 更新操作
post_delete:function(req,res){
db.member.update({name:'新生帝'},{
where:{
id:10
}
}).then(function(msg){
// 更新成功
console.log(msg);
});
},
// 根据主键查询一条
get_id:function(req,res){
db.member.findById(10).then(function(data){
// 查询成功
console.log(data);
});
},
// 根据条件查询一条
get_one:function(req,res){
db.member.findOne({
where:{
name:"百小僧"
}
}}).then(function(data){
// 查询成功
console.log(data);
});
},
// 查询所有
get_all:function(req,res){
db.member.findAll().then(function(data){
// 查询成功
console.log(data);
});
},
// 根据条件查询
get_all:function(req,res){
db.member.findAll({
where:{
id:{
$gt:2
}
}
}).then(function(data){
// 查询成功
console.log(data);
});
},
// 分页查询
get_all:function(req,res){
db.member.findAll({
offset: 10,
limit: 2,
where:{
isDel:false
}
}).then(function(data){
// 查询成功
console.log(data);
});
}
};
```### Session,Cookies
> Session、Cookies主要用户存储客户端会话信息,通常用于登录判断
- Session 使用
```
module.exports={
get_index:function(req,res){
// 检查 session 中的 isVisit 字段
// 如果存在则增加一次,否则为 session 设置 isVisit 字段,并初始化为 1。
if(req.session.isVisit) {
req.session.isVisit++;
res.send('第 ' + req.session.isVisit + '次来此页面
');
} else {
req.session.isVisit = 1;
res.send("欢迎第一次来这里");
console.log(req.session);
}
}
}
```- Cookies 使用
```
module.exports={
get_index:function(req,res){
// 如果请求中的 cookie 存在 isVisit, 则输出 cookie
// 否则,设置 cookie 字段 isVisit, 并设置过期时间为1分钟
if (req.cookies.isVisit) {
console.log(req.cookies);
res.send("再次欢迎访问");
} else {
res.cookie('isVisit', 1, {maxAge: 60 * 1000});
res.send("欢迎第一次访问");
}
}
}
```### 过滤器、中间件
> 过滤器,中间件主要对请求进行过滤的
- 在控制器中直接使用
```
module.exports={
get_admin:[function(req,res,next){
if(未登录){
res.redirect("登录页面");
}
else{
next();
}
},function(req,res){
res.send("ok");
}]
};
```- 全局过滤器,将过滤器定义到`filters`文件夹下,如创建一个`loginFilter.js`
```
module.exports = function (req, res, next) {
if(未登录){
res.redirect("登录页面");
}
else{
next();
}
};
```在控制器中使用
```
var loginFilter = require("../../../filters/loginFilter");
module.exports={
get_admin:[loginFilter,function(req,res){
res.send("ok");
}]
}
```- 多个过滤器
```
module.exports={
get_admin:[function(req,res,next){
console.log("日志记录");
next();
},function(req,res,next){
if(未登录){
res.redirect("登录页面");
}
else{
next();
}
},function(req,res){
res.send("ok");
}]
};
```### 表单提交
- 视图布局:
```
表单(不带文件上传,不带: enctype="multipart/form-data"):
表单(不带文件上传,带: enctype="multipart/form-data"):
表单(带单个文件上传,带: enctype="multipart/form-data"):
表单(带多个文件上传,带: enctype="multipart/form-data"):
表单(带多个文件上传,上传表单名称 不一样(file1,file2,...),带: enctype="multipart/form-data"):
```- 控制器Action处理:
```
var multer = require('multer');module.exports = {
// 表单(不带文件上传,不带: enctype="multipart/form-data")
post_form1: function (req, res) {
res.json(req.body);
},
// 表单(不带文件上传,带: enctype="multipart/form-data"):
post_form2: [multer().array(), function (req, res) {
res.json(req.body);
}],
// 表单(带单个文件上传,带: enctype="multipart/form-data"):
post_form3: [multer().single('file1'), function (req, res) {
res.send("文件:" + JSON.stringify(req.file) + "
表单" + JSON.stringify(req.body))
}],
// 表单(带多个文件上传,带: enctype="multipart/form-data"):
post_form4: [multer().array('file1'), function (req, res) {
res.send("文件:" + JSON.stringify(req.files) + "
表单" + JSON.stringify(req.body))
}],
// 表单(带多个文件上传,上传表单名称 不一样(file1,file2,...),带: enctype="multipart/form-data"):
post_form5: [multer().fields([{ name: "file1" }, { name: "file2" }]), function (req, res) {
res.send("文件:" + JSON.stringify(req.files) + "
表单" + JSON.stringify(req.body))
}]
};
```详细文档,请参考:[multer 文档](https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md)
### 文件上传
> 文件上传集成强大的`multer`组件,[详细文档](https://www.npmjs.com/package/multer)
- 客户端
```
```
- 服务端
```
var path = require('path');
var fs = require('fs');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });module.exports = {
post_upload: [upload.single('logo'), function(req, res, next) {
var file = req.file;
var ext = path.extname(file.originalname);
fs.rename(file.path, file.path + ext, function(err) {
if (err) {
res.send(JSON.stringify(err));
}
next();
});
}, function(req, res) {
res.send("上传成功");
}]
}
```### Redis存储
> 集成了 `redis` 模块,[文档地址](https://www.npmjs.com/package/redis)
- 基础使用
```
var redis = require("redis"),
client = redis.createClient();// if you'd like to select database 3, instead of 0 (default), call
// client.select(3, function() { /* ... */ });client.on("error", function (err) {
console.log("Error " + err);
});client.set("string key", "string val", redis.print);
client.hset("hash key", "hashtest 1", "some value", redis.print);
client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
client.hkeys("hash key", function (err, replies) {
console.log(replies.length + " replies:");
replies.forEach(function (reply, i) {
console.log(" " + i + ": " + reply);
});
client.quit();
});
```### WebSocket
> 框架已经集成了socket.io ,可以开发实时通信,聊天等应用,[详细文档](http://socket.io/)
- 服务端代码,`utils/socket.js`
```
var io = require('socket.io')();// socket.io 基础使用,监听连接请求
io.on('connection', function (socket) {
console.log("客户端连接成功~~");// 监听来自客户端事件
socket.on('send', function (data) {
// 调用客户端receive事件,并传递data
io.emit('receive', data);
});// 这里就写各种监听事件就可以了,
// 通过 socket.on("") 监听客户端事件,通过 io.emit("") 触发所有客户端事件,socket.emit("") 触发指定客户端});
exports.listen = function (server) {
return io.listen(server);
};
```- 客户端代码
```
// 连接服务器
var socket = io.connect('http://localhost:3000/');window.onload=function(){
var send=document.getElementById("send");
send.onclick=function(){
var name=document.getElementById("name").value;
var msg=document.getElementById("msg").value;// 发送消息
socket.emit('send', { data:name+":"+msg });
};// 监听服务器消息
socket.on('receive', function (data) {
console.log(data);
var list = document.getElementById("list");
// 写入聊天列表
list.innerHTML=list.innerHTML+"<br />"+data.data;
// 清空msg
document.getElementById("msg").value="";
});
};```
### 防止csurf攻击
- 服务端
```
var csrf = require('csurf');
var csrfProtection = csrf({ cookie: true });
module.exports={
post_login:[csrfProtection,function(req,res){
res.send("ok",{ csrfToken: req.csrfToken() });
}]
};
```- 客户端
```
Favorite color:
Submit```
### 生成环境部署
- 安装pm2
```
$ npm install pm2 -g |$ pm2 start app.js
```- 设置随机启动
```
$ npm install pm2-windows-startup -g$ pm2-startup install
$ pm2 save
```## 友情捐赠
如果你觉得 Monk.Node 对你有价值,并且愿意让她继续成长下去,你可以资助这个项目的开发,为作者加油打气。
![微信捐赠](http://images.cnblogs.com/cnblogs_com/baisoft/865458/o_%e6%8d%90%e8%b5%a0.png)
如果你喜欢Monk.Node,可以点击右上角的 `star`,想实时关注进度,可以点击右上角的 `watch`。
最后,感谢每一个提建议和使用或者捐赠的朋友!因为你们,我们才能坚持!也是因为你们,未来才会更美好!