在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:Monk.Node开源软件地址:https://gitee.com/monksoul/Monk.Node开源软件介绍:Monk.Node — 极易入门的Node.JS MVC 框架Monk.Node 是一个免费开源的,快速、简单的面向对象的轻量级Node.JS开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。Monk.Node从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。遵循MIT开源许可协议发布,意味着你可以免费使用Monk.Node,甚至允许把你基于Monk.Node开发的应用开源或商业产品发布/销售。
主要特性
Monk.Node 目前还在持续新增更多新特性,新功能,更多特性可持续关注项目更新。
作者信息
视频教程
更新记录============ 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 clone https://git.oschina.net/baisoft_org/Monk.Node.git$ cd Monk.Node$ npm install$ npm start浏览器:http://localhost:3000/
浏览器访问:http://git.oschina.net/baisoft_org/Monk.Node$ cd Monk.Node$ npm install$ npm start浏览器:http://localhost:3000/ 全局数据注入(v2.2.5 支持)全局数据注入 表示可以在 例如:在locals文件夹下定义 module.exports = { "name": "Monk.Node", "version": "2.2.5", "author": "百小僧", "company": "百签软件(中山)有限公司"};
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 }};
<%=_locals.setting.name %><%=_locals.setting.version %><%=_locals.setting.company %> 当然,我们也可以定义局部数据注入,局部数据注入通常在 module.exports={ get_index:function(req,res){ res.locals.abc="我是局部的。。。。。"; }};
<%=_locals.abc %> 全局数据注入使用非常灵活,可以结合数据库操作,最终通过 入口配置
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
// cookie处理app.use(cookieParser());// session处理app.use(session({ secret: 'monknode', cookie: { maxAge: 60000 }, resave: true, saveUninitialized: true}));
// 设置控制器文件夹并绑定到路由resolve .setRouteDirectory({ areaDirectory: __dirname + '/areas', controllerDirname: 'controllers', defautController: 'home', defautAction: 'index' }) .bind(router);
// 错误处理// 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('<pre>' + status + ' ' + err.message + '\n' + errorMes + '</pre>');});
app.set('port', process.env.PORT || 3000);
require(path.join(__dirname, 'utils', 'socket')).listen(server); 区域
只需要在 默认已经包含
http://localhost:3000/backend/http://localhost:3000/frontend/http://localhost:3000/api/ 控制器
module.exports={};
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"); }],}; 视图模板引擎
<% if (user) { %> <h2><%= user.name %></h2><% } %>
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:"百小僧"}) %> 静态资源
<img src="/imgs/logo.png" /><link res="stylesheet" href="/css/style.css" /><script type="text/javascript" src="/js/script.js"></script> 模型
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 });}; 由于构建模型是非常耗时而且重复代码多,所以本框架提供了数据表模型生成工具,通过下面地址可以快速构建模型,无需手工操作 生成前需配置 http://localhost:3000/tools/generate/models 数据库CURD数据库操作集成强大的ORM框架:Sequelize.js,支持目前所有主流数据库,详细文档
{ // 开发环境 "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 } }}
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
module.exports={ get_index:function(req,res){ // 检查 session 中的 isVisit 字段 // 如果存在则增加一次,否则为 session 设置 isVisit 字段,并初始化为 1。 if(req.session.isVisit) { req.session.isVisit++; res.send('<p>第 ' + req.session.isVisit + '次来此页面</p>'); } else { req.session.isVisit = 1; res.send("欢迎第一次来这里"); console.log(req.session); } }}
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"); }]};
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"); }]}; 表单提交
<h3>表单(不带文件上传,不带: enctype="multipart/form-data"):</h3> <form action="/backend/home/form1" method="post"> <input type="text" name="name" /> <input type="submit" value="提交"> </form> <h3>表单(不带文件上传,带: enctype="multipart/form-data"):</h3> <form action="/backend/home/form2" method="post" enctype="multipart/form-data"> <input type="text" name="name" /> <input type="submit" value="提交"> </form> <h3>表单(带单个文件上传,带: enctype="multipart/form-data"):</h3> <form action="/backend/home/form3" method="post" enctype="multipart/form-data"> <input type="file" name="file1"> <input type="text" name="name" /> <input type="submit" value="提交"> </form> <h3>表单(带多个文件上传,带: enctype="multipart/form-data"):</h3> <form action="/backend/home/form4" method="post" enctype="multipart/form-data"> <input type="file" name="file1"> <input type="file" name="file1"> <input type="text" name="name" /> <input type="submit" value="提交"> </form> <h3>表单(带多个文件上传,上传表单名称 不一样(file1,file2,...),带: enctype="multipart/form-data"):</h3> <form action="/backend/home/form5" method="post" enctype="multipart/form-data"> <input type="file" name="file1"> <input type="file" name="file2"> <input type="text" name="name" /> <input type="submit" value="提交"> </form>
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) + "<br />表单" + JSON.stringify(req.body)) }], // 表单(带多个文件上传,带: enctype="multipart/form-data"): post_form4: [multer().array('file1'), function (req, res) { res.send("文件:" + JSON.stringify(req.files) + "<br />表单" + 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) + "<br />表单" + JSON.stringify(req.body)) }]}; 详细文档,请参考:multer 文档 文件上传
<form action="/upload" method="post" enctype="multipart/form-data"> <input type="file" name="logo"> <input type="submit" value="提交"></form>
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存储
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
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);};
<!-- 引入客户端脚本 --> <script src="/vendors/socket.io/socket.io.js"></script> <script> // 连接服务器 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=""; }); };</script> 防止csurf攻击
var csrf = require('csurf');var csrfProtection = csrf({ cookie: true });module.exports={ post_login:[csrfProtection,function(req,res){ |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论