【4858美高梅】NodeJs服务器安插篇,mysql完毕restful风格的增加和删除改查示例

By admin in 4858美高梅 on 2019年5月4日

=====================================================================

第3,放上项目github地址:

先是,放上项目github地址:

亟需安装的模块

*监察和控制种类预览地址:* 预览地址

一、前言

在此之前学的java,一贯用的ssm框架写后台。上个月接触到node.js,于是花了两日时间学了壹晃node.js并写了贰个CRUD简单示例。由于前些天一贯学用github
pages搭建博客,一向没时间写README,今日有空补了上来。

下边来内容自于项目标README。

一、前言

事先学的java,平素用的ssm框架写后台。前3个月接触到node.js,于是花了两日时间学了瞬间node.js并写了三个CRUD轻巧示例。由于前日一贯学用github
pages搭建博客,一向没时间写README,今日有空补了上去。

上边来内容自于项目的README。

  • body-parser 解析post请求
  • cookies 读写cookie
  • express 搭建服务器
  • markdown 马克down语法解析生成器
  • mongoose 操作Mongodb数据库
  • swig 模板解析引擎

=====================================================================

【4858美高梅】NodeJs服务器安插篇,mysql完毕restful风格的增加和删除改查示例。二、项目介绍

听别人讲node.js + express + mysql落成的restful风格的CRUD容易示例

2、项目介绍

基于node.js + express + mysql实现的restful风格的CRUD简单示例

目录结构

  JS错误消息已经有措施搜聚了,那么如何存下来,怎么着剖析出来有价值的数量,这都急需依赖后台代码的效应了

2.壹 组织结构

├── app.js -- 应用配置
├── bin
│   └── www -- 项目运行脚本
├── conf 
│   └── mysqlConf.js -- mysql配置文件
├── dao
│   ├── userDAO.js -- 封装和数据库的交互
│   └── userSqlMap.js -- SQL语句封装
├── model
│   └── result.js -- 返回结果对象封装
├── package.json -- 依赖模块
├── project-datamodel
│   └── user.sql -- 数据库脚本
├── public -- 前端静态页面
│   ├── add.html
│   ├── css
│   │   └── style.css
│   ├── detail.html
│   ├── index.html
│   └── modify.html
└── routes
    └── users.js -- 用户操作路由及业务逻辑

二.1 协会结构

├── app.js -- 应用配置
├── bin
│   └── www -- 项目运行脚本
├── conf 
│   └── mysqlConf.js -- mysql配置文件
├── dao
│   ├── userDAO.js -- 封装和数据库的交互
│   └── userSqlMap.js -- SQL语句封装
├── model
│   └── result.js -- 返回结果对象封装
├── package.json -- 依赖模块
├── project-datamodel
│   └── user.sql -- 数据库脚本
├── public -- 前端静态页面
│   ├── add.html
│   ├── css
│   │   └── style.css
│   ├── detail.html
│   ├── index.html
│   └── modify.html
└── routes
    └── users.js -- 用户操作路由及业务逻辑
  • db 数据仓库储存储目录
  • models 数据库模型文件目录
  • public 公共文件目录(css,js,img)
  • routers 路由文件目录
  • schemas 数据库结构文件
  • views 模板视图像和文字件目录
  • app.js 运转文件
  • package.json

  作为前端程序猿,首荐NodeJs作为后台语言,MySQL数据库,Koa贰看作框架,为了分析出有用的结果,须要进行三个sql的查询,那年async/await就起了相当大功能。最要害的就是那多少个工具才干,其实小编早就将代码放到GitHub上了,这一章讲起来,认为微微多余了,因为看代码更便于明白当中是怎么回事,就大约的牵线一下用法。

二.二 模块注重

www -> app.js -> users.js ->  userDAO.js -> mysqlConf.js & userSqlMap.js

二.2 模块依赖

www -> app.js -> users.js ->  userDAO.js -> mysqlConf.js & userSqlMap.js

app.js 文件

  壹、目录结构

二.3 技巧选型

后端才干

  • node.js
  • express

前者才能

  • angular.js

二.三 本领选型

后端技艺

  • node.js
  • express

前端才具

  • angular.js

壹.创办应用、监听端口

  三个档期的顺序前景是否能够特出拓展,项目协会自然要搭建好,便于梳理逻辑。如图:

3、情形搭建

  • node.js:
  • mysql:

叁、情形搭建

  • node.js:
  • mysql:
const app = express();

app.get('/',(req,res,next) => {
  res.send("Hello World !");
});
app.listen(3000,(req,res,next) => {
  console.log("app is running at port 3000");
});

   4858美高梅 1

四、项目运维

  1. 下载代码并布置

git clone https://github.com/codethereforam/express-mysql-demo.git
cd express-mysql-demo && npm install   #安装部署依赖的包
  1. 新建express-mysql-demo数据库,导入project-datamodel文件夹下的user.sql

  2. 修改conf/mysqlConf.js中数据库配置消息

  3. 启动

# 切换到项目根路径
npm start
  1. 开荒首页:

4、项目运维

  1. 下载代码并配置

git clone https://github.com/codethereforam/express-mysql-demo.git
cd express-mysql-demo && npm install   #安装部署依赖的包
  1. 新建express-mysql-demo数据库,导入project-datamodel文件夹下的user.sql

  2. 修改conf/mysqlConf.js中数据库配置新闻

  3. 启动

# 切换到项目根路径
npm start
  1. 开发首页:

二.布局利用模板

  /bin :安排有关(本地,测试,生产条件)

伍、开垦进度及代码分析

关于restful,可参照阮壹峰的两篇文章:

  • 理解RESTful架构
  • RESTful API
    设计指南

自个儿动用的IDE是IDEA,安装”NodeJS”插件后挨家挨户点击

File -> New Project -> Node.js and NPM -> Node.js Express App

IDEA暗中同意使用express-generator生成项目协会。

新建数据库”express-mysql-demo”:

create database `express-mysql-demo`;

新建user表:

CREATE TABLE `express-mysql-demo`.`user` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(45) NOT NULL,
  `password` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`))
DEFAULT CHARACTER SET = utf8mb4;

表结构:

+----------+------------------+------+-----+---------+----------------+
| Field    | Type             | Null | Key | Default | Extra          |
+----------+------------------+------+-----+---------+----------------+
| id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| username | varchar(45)      | NO   |     | NULL    |                |
| password | varchar(45)      | NO   |     | NULL    |                |
+----------+------------------+------+-----+---------+----------------+

mysql配置文件conf/mysqlConf.js:

module.exports = {
    mysql: {
        host: 'localhost',
        user: 'root',
        password: '',
        database:'express-mysql-demo',
        // 最大连接数,默认为10
        connectionLimit: 10
    }
};

SQL语句封装模块dao/userSqlMap.js:

var userSqlMap = {
    add: 'insert into user(username, password) values(?, ?)',
    deleteById: 'delete from user where id = ?',
    update: 'update user set username=?, password=? where id=?',
    list: 'select * from user',
    getById: 'select * from user where id = ?'
};

包装再次来到结果对象model/result.js:

exports.createResult = function(success, data) {
    var result = {};
    result.success = success;
    result.data = data;
    return result;
};

本人这里运用了工厂方法创立结果对象,对象有五个天性,success代表用户操作成功或战败,data存放后台要回来的数目。

下边分析修改用户部分消息的有关代码,全体的增加和删除改查代码请将项目clone下来翻看。

打包和数据库的并行模块dao/userDAO.js:

var pool = mysql.createPool(mysqlConf.mysql);
module.exports = {
     getById: function (id, callback) {
        pool.query(userSqlMap.getById, id, function (error, result) {
            if (error) throw error;
            console.log(result[0]);
            callback(result[0]);
        });
    },update: function (user, callback) {
        pool.query(userSqlMap.update, [user.username, user.password, user.id], function (error, result) {
            if (error) throw error;
            callback(result.affectedRows > 0);
        });
    }
};

此间运用了连接池,重复使用数据库连接,而无需每实行三次CRUD操作就拿走、释放三次数据库连接,从而抓好了对数据库操作的天性。

用户操作路由及贯彻业务逻辑routes/users.js:

/* patch users */
router.patch('/:id', function (req, res) {
    console.log('patch users called');
    userDAO.getById(req.params.id, function (user) {
        var username = req.body.username;
        if(username) {
            user.username = username;
        }
        var password = req.body.password;
        if(password) {
            user.password = password;
        }
        console.log(user);
        userDAO.update(user, function (success) {
            var r =  result.createResult(success, null);
            res.json(r);
        });
    });
});

router依照分化的HTTP请求方法和访问路线实行相应的回调函数,回调函数中先记下日志,然后检查用户传过来的数额,接着调用userDAO的相应CRUD方法,最终回来多少个JSON对象给前端。这里修改用户部分音讯对应HTTP方法是PATCH,而修改总体消息对应的是PUT。

应用配置app.js中安插用户操作相关的路由:

app.use('/users', users);

前端public/index.html中与后台交互的JS代码:

(function (window) {
            window.angular.module('list', [])
                .controller('listCtrl', function ($scope, $http) {                
                    $scope.doPatch = function (id) {
                        var data = JSON.stringify({
                            password: document.getElementById("pwd" + id).value
                        });
                        $http.patch("/users/" + id, data)
                            .then(function (response) {
                                console.debug(response.data.success);
                            }, function (err) {
                                alert(err);
                            });
                    };
                });
        })(window);

前端选择angualr.js,ajax异步调用后端restful
API,然后解析后台再次回到的JSON对象在分界面上显得。

五、开垦进程及代码分析

关于restful,可参照阮1峰的两篇文章:

  • 理解RESTful架构
  • RESTful API
    设计指南

作者动用的IDE是IDEA,安装”NodeJS”插件后逐一点击

File -> New Project -> Node.js and NPM -> Node.js Express App

IDEA暗中同意使用express-generator生成项目组织。

新建数据库”express-mysql-demo”:

create database `express-mysql-demo`;

新建user表:

CREATE TABLE `express-mysql-demo`.`user` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(45) NOT NULL,
  `password` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`id`))
DEFAULT CHARACTER SET = utf8mb4;

表结构:

+----------+------------------+------+-----+---------+----------------+
| Field    | Type             | Null | Key | Default | Extra          |
+----------+------------------+------+-----+---------+----------------+
| id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| username | varchar(45)      | NO   |     | NULL    |                |
| password | varchar(45)      | NO   |     | NULL    |                |
+----------+------------------+------+-----+---------+----------------+

mysql配置文件conf/mysqlConf.js:

module.exports = {
    mysql: {
        host: 'localhost',
        user: 'root',
        password: '',
        database:'express-mysql-demo',
        // 最大连接数,默认为10
        connectionLimit: 10
    }
};

SQL语句封装模块dao/userSqlMap.js:

var userSqlMap = {
    add: 'insert into user(username, password) values(?, ?)',
    deleteById: 'delete from user where id = ?',
    update: 'update user set username=?, password=? where id=?',
    list: 'select * from user',
    getById: 'select * from user where id = ?'
};

装进重临结果对象model/result.js:

exports.createResult = function(success, data) {
    var result = {};
    result.success = success;
    result.data = data;
    return result;
};

自家这边运用了工厂方法成立结果对象,对象有五个属性,success代表用户操作成功或倒闭,data存放后台要赶回的数据。

上边分析修改用户部分音信的相关代码,全体的增加和删除改查代码请将品种clone下来查看。

包裹和数据库的互动模块dao/userDAO.js:

var pool = mysql.createPool(mysqlConf.mysql);
module.exports = {
     getById: function (id, callback) {
        pool.query(userSqlMap.getById, id, function (error, result) {
            if (error) throw error;
            console.log(result[0]);
            callback(result[0]);
        });
    },update: function (user, callback) {
        pool.query(userSqlMap.update, [user.username, user.password, user.id], function (error, result) {
            if (error) throw error;
            callback(result.affectedRows > 0);
        });
    }
};

那边运用了连接池,重复使用数据库连接,而不用每实践壹回CRUD操作就获取、释放贰次数据库连接,从而加强了对数据库操作的性质。

用户操作路由及落到实处工作逻辑routes/users.js:

/* patch users */
router.patch('/:id', function (req, res) {
    console.log('patch users called');
    userDAO.getById(req.params.id, function (user) {
        var username = req.body.username;
        if(username) {
            user.username = username;
        }
        var password = req.body.password;
        if(password) {
            user.password = password;
        }
        console.log(user);
        userDAO.update(user, function (success) {
            var r =  result.createResult(success, null);
            res.json(r);
        });
    });
});

router依照分歧的HTTP请求方法和走访路线试行相应的回调函数,回调函数中先记下日志,然后检查用户传过来的数目,接着调用userDAO的照拂CRUD方法,最后回到八个JSON对象给前端。这里修改用户部分新闻对应HTTP方法是PATCH,而修改总体新闻对应的是PUT。

使用配置app.js中配备用户操作相关的路由:

app.use('/users', users);

前者public/index.html中与后台交互的JS代码:

(function (window) {
            window.angular.module('list', [])
                .controller('listCtrl', function ($scope, $http) {                
                    $scope.doPatch = function (id) {
                        var data = JSON.stringify({
                            password: document.getElementById("pwd" + id).value
                        });
                        $http.patch("/users/" + id, data)
                            .then(function (response) {
                                console.debug(response.data.success);
                            }, function (err) {
                                alert(err);
                            });
                    };
                });
        })(window);

前端选取angualr.js,ajax异步调用后端restful
API,然后解析后台重返的JSON对象在分界面上显得。

  • 概念使用的沙盘引擎 app.engine(‘html’,swig.renderFile)
    参数一:模板引擎的称号,同时也是模板文件的后缀
    参数二:表示用于解析管理模板内容的章程
  • 设置模板文件存放的目录 app.set(‘views’,’./views’)
  • 挂号所采纳的模板引擎 app.set(‘view engine’,’html’)

  /config :配置相关(数据库配置)

3.用模板引擎去分析文件

  /controllers :调控器层(管理千头万绪的逻辑关系)

/**
 * 读取views目录下的指定文件,解析并返回给客户端 
 * 参数1:模板文件
 * 参数2:给模板传递的参数 
 */

res.render('index',{
  title:'首页 ',
  content: 'hello swig'
});

  /middlreware : 中间件(主要做校验的逻辑)

四.花费进度中要求打消模板缓存的限量

  /modules : 模块(区分业务模块)

swig.setDefaults({
 cache: false
});
app.set('view cache', false);

  /routes :路由(区分接口路由)

伍.装置静态文件托管

  /schema : model层(主要是目的和数据库的映照)

 // 当用户访问的是/public路径下的文件,那么直接返回
app.use('/public',express.static(__dirname + '/public'));

  /templates : 模板(首假如为着壹键生成新的模块,进步支付功能)

分割模块

  /util :自定义组件、工具

  • 前台模块
  • 后台模块
  • API模块

  /app.js :入口文件

// 根据不同的功能划分模块
app.use('/',require('./routers/main'));
app.use('/admin',require('./routers/admin'));
app.use('/api',require('./routers/api'));

  /createModule.js :创制新模块命令

对此管理员模块 admin.js

  贰、创造新模块

var express = require('express');
var router = express.Router();

// 比如访问 /admin/user
router.get('/user',function(req,res,next) {
  res.send('User');
});
module.exports = router;

  一 配置数据库连接

前台路由 + 模板

const sequelizeTemp = require('./local_db')
const Sequelize = require('sequelize');
let db = null
if (sequelizeTemp) {
  db = sequelizeTemp.sequelize
} else {
  const sequelize = new Sequelize('monitor_db', 'username', 'password', {
    host: 'ip',
    dialect: 'mysql',
    operatorsAliases: false,
    dialectOptions: {
      charset: "utf8mb4",
      collate: "utf8mb4_unicode_ci",
      supportBigNumbers: true,
      bigNumberStrings: true
    },
    pool: {
      max: 5,
      min: 0,
      acquire: 30000,
      idle: 10000
    },
    timezone: '+08:00' //东八时区
  });
  db = sequelize
}
module.exports = {
  sequelize: db
}

main 模块
/ 首页
/view 内容页

 

4858美高梅 ,api模块

  贰开立新模块 node createModule.js NewModule

/首页
/register 用户注册
/login 用户登陆
/comment 斟酌得到
/comment/post 钻探提交

4858美高梅 2

后台(admin)路由+模板

  如此会生成新的model,大家须求在当中配置数据库相关的字段,那样就足以跟mysql形成映射关系,就没有要求在数据库中国建工业总会公司表。以js错误的model为例,在那之中baseInfo为通用属性方法,会为model增添通用的品质:

首页

const baseInfo = require('./baseInfo');
module.exports = function (sequelize, DataTypes) {
  return sequelize.define('JavascriptErrorInfo', {
    ...baseInfo(DataTypes),
    // ID 主键
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
      allowNull: false,
      autoIncrement: true,
    },
    // JS报错信息
    errorMessage: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'errorMessage'
    },
    // JS报错堆栈
    errorStack: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'errorStack'
    },
    // 浏览器信息
    browserInfo: {
      type: DataTypes.TEXT,
      allowNull: true,
      field: 'browserInfo'
    },
  }, {
    // 如果为 true 则表的名称和 model 相同,即 user
    // 为 false MySQL创建的表名称会是复数 users
    // 如果指定的表名称本就是复数形式则不变
    freezeTableName: false
  })

}

/ 后台首页

  叁处理modules和controllers层里边的逻辑

用户处理

  四为接口增多路由代码

/user 用户列表

const Router = require('koa-router')
const UserController = require('../controllers/user')
const ProjectController = require('../controllers/project')
const BehaviorInfoController = require('../controllers/behaviorInfo')
const JavascriptErrorInfo = require('../controllers/javascriptErrorInfo')
const CustomerPVController = require('../controllers/customerPV')
const CommonController = require('../controllers/common')
const router = new Router({
    prefix: '/api/v1'
})

/**
 * 日志相关处理
 */
// 用户注册
router.post('/uploadLog', CommonController.uploadLog);

/**
 * 用户接口
 */
// 用户注册
router.post('/user', UserController.create);
// 用户登录
router.post('/user/login', UserController.login);
// 获取用户信息
router.get('/user', UserController.getUserInfo);
// 获取用户列表
router.get('/user/list', UserController.getUserList);
// 删除用户
router.delete('/user/:id', UserController.delete);

...

module.exports = router

分类处理

  伍执行命令 npm run start , 就能够在mysql数据库中创立数量库表

/category 分类列表
/category/add 分类加多
/category/edit 分类修改
/caterory/delete 分类删除

4858美高梅 3

小说内容管理

  

/article nei内容列表
/article/add 内容丰硕
/article/edit 内容改造
/article/delete 内容删除

  到此,后台服务器便可成功运维了

评价内容管理

 

/comment 探究列表
/comment/delete 批评删除

  上一章: 搭建前端监察和控制系统(2)JS错误监控篇

功能开辟顺序

  下一章: 搭建前端监察和控制系统(4)展现平台安插篇

功用模块开荒顺序

 

  • 用户
  • 栏目
  • 内容
  • 评论

编码顺序

  • 透过Schema定义设计数据存款和储蓄结构
  • 功用逻辑
  • 页面突显

一连数据库(mongoDB)

启动MongoDB服务端:

mongod –dbpath=G:\data\db –port=27017

开发银行服务设置数据库的囤积地方以及端口

var mongoose = require('mongoose');
// 数据库链接
mongoose.connect("mongodb://localhost:27017/blog",(err) => {
  if(err){
    console.log("数据库连接失败");
  }else{
    console.log("数据库连接成功");
   // 启动服务器,监听端口 
   app.listen(3000,(req,res,next) => {
      console.log("app is running at port 3000");
    });
  }
});

概念数据表结构和模型

对此用户数据表(users.js)在schema文件夹下:

var mongoose = require('mongoose');
module.exports = new mongoose.Schema({
  // 用户名
  username:String,
  // 密码
  password:String
});

在models目录下开创user.js模型类

var mongoose = require('mongoose');
var userSchema = require('../schemas/users');
module.exports = mongoose.model('User',userSchema);

管理用户注册

前者通过ajax提交用户名和密码

url: /api/register

后端对前者提交(POST)的数码解析

var bodyParser = require('body-parser');
// bodyParser 配置
// 通过使用这一方法,可以为req对象添加一个body属性
app.use( bodyParser.urlencoded({extended:true}));

// 在api模块中:
// 1.可以定义一个中间件,来统一返回格式
var responseData;
router.use( function(req,res,next){ // path默认为'/',当访问该目录时这个中间件被调用
  responseData = {
     code:0,
    message:''
  };
  next();
});

router.post('/register',(req,res,next) => {
  console.log(req.body);
  // 去判断用户名、密码是否合法
  // 判断是否用户名已经被注册
  // 通过 res.json(responseData) 给客户端返回json数据

  // 查询数据库
  User.findOne({  // 返回一个promise对象
      username: username
  }).then(function( userInfo ) {
      if( userInfo ){ // 数据库中有该条记录
      ...
     res.json(responseData);
     return;
    }
    // 给数据库中添加该条信息
    var user = new User({ username:username,password:password });
    return user.save(); // 返回promise对象
  }).then(function( newUserInfo ){
      console.log(newUserInfo);
    res.json(responseData); // 数据保存成功 
  });
});

cookies 模块的施用

大局(app.js)注册使用

// 设置cookie
// 只要客户端发送请求就会通过这个中间件
app.use((req, res, next) => {
  req.cookies = new cookies(req, res);

  /**
   * 解析用户的cookies信息
   * 查询数据库判断是否为管理员 isAdmin
   * 注意:查询数据库是异步操作,next应该放在回调里边
   */
  req.userInfo = {};
  if (req.cookies.get("userInfo")) {
    try {
      req.userInfo = JSON.parse(req.cookies.get("userInfo"));
      // 查询数据库判断是否为管理员
      User.findById(req.userInfo._id).then(function (result) {
        req.userInfo.isAdmin = Boolean(result.isAdmin);
        next();
      });
    } catch (e) {
      next();
    }
  } else {
    next();
  }
});

// 当用户登录或注册成功之后,可以为其设置cookies
req.cookies.set("userInfo",JSON.stringify({
   _id:result._id,
  username:result.username 
}));

swig模板引擎

1.变量

{{ name }}

2.属性

{{ student.name }}

3.if判断

{ % if name === ‘郭靖’ % }

hello 靖哥哥

{ % endif % }

4.for循环

// arr = [1, 2, 3]

{ % for key, val in arr % }

<p>{ { key } } — { { val } }</p>

{ % endfor % }

5.set命令

用来安装一个变量,在当前上下文中复用

{% set foo = [0, 1, 2, 3, 4, 5] %}

{% extends ‘layout.html’ %} // 承接某1个HTML模板
{% include ‘page.html’ %} // 包蕴二个模板到方今职分
{% block main %} xxx {% endblock %} //重写某一区块

陆.autoescape 自动编码

当想在某些div中展现后端生成的HTML代码,模板渲染时会自动编码,
以字符串的花样显得。通过以下格局,能够幸免这一个情况:

<div id="article-content" class="content">
  {% autoescape false %}
  {{ data.article_content_html }}
  {% endautoescape %}
</div>

用户管理和分页

CRUD用户数据

const User = require('../models/user');

// 查询所有的用户数据
User.find().then(function(users){

});

// 根据某一字段查询数据
User.findOne({
  username:username
}).then(function(result){

});

// 根据用户ID查询数据
User.findById(id).then(function(user){

});

// 根据ID删除数据
User.remove({
  _id: id
}).then(function(){

});

// 修改数据
User.update({
  _id: id
},{
  username: name
}).then(function(){ 
});

数量分页管理

七个主要艺术

limit(Number): 限制获取的数目条数

skip(Number): 忽略数据的条数 前number条

概况条数:(当前页 – 一) * 每页展现的条数

// 接收传过来的page
let query_page = Number(req.query.page) || 1;
query_page = Math.max(query_page, 1); // 限制最小为1
query_page = Math.min(Math.ceil(count / limit), query_page); // 限制最大值 count/limit向上取整


var cur_page = query_page; // 当前页
var limit = 10; // 每页显示的条数
var skip = (cur_page - 1) * limit; //忽略的条数

User.find().limit(limit).skip(skip).then(function(users){
  ...
 // 将当前页 page 传给页面
 // 将最大页码 maxPage 传给页面
});

小说的表结构

// 对于content.js
var mongoose = require('mongoose');
var contentSch = require('../schemas/contentSch');

module.exports = mongoose.model('Content',contentSch);


// contentSch.js
module.exports = new mongoose.Schema({

  // 关联字段 - 分类的id
  category:{
    // 类型
    type:mongoose.Schema.Types.ObjectId,
    // 引用
    ref:'Category' 
  },

  // 内容标题
  title: String,

  // 简介
  description:{
    type: String,
    default: '' 
  },

  // 内容
  content:{
    type:String,
    default:''
  }
});

// 文章查询时关联category字段
Content.find().populate('category').then(contents => {
  // 那么通过这样的方式,我们就可以找到Content表中的
  // 关联信息   content.category.category_name 
});

马克Down语法高亮

在HTML中央直机关接行使

<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
<script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>

<script src="https://cdn.bootcss.com/marked/0.3.17/marked.min.js"></script>

// marked相关配置
marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: true,
  smartLists: true,
  smartypants: false,
  highlight: function (code) {
    return hljs.highlightAuto(code).value;
  }
});

// MarkDown语法解析内容预览
$('#bjw-content').on('keyup blur', function () {
  $('#bjw-previous').html(marked($('#bjw-content').val()));
});

node意况中应用

// 在模板页面引入默认样式
<!--语法高亮-->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">

const marked = require('marked');
const hljs = require('highlight.js');

// marked相关配置
marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: true,
  smartLists: true,
  smartypants: false,
  highlight: function (code) {
    return hljs.highlightAuto(code).value;
  }
});

// 对内容进行markdown语法转换
data.article_content_html = marked(article.content);

使文本域援助Tab缩进

$('#bjw-content').on('keydown',function(e){
  if(e.keyCode === 9){ // Tab键
     var position = this.selectionStart + 2; // Tab === 俩空格
    this.value = this.value.substr(0,this.selectionStart) + " " + this.value.substr(this.selectionStart);
    this.selectionStart = position;
    this.selectionEnd = position;
    this.focus();
    e.preventDefault();
  }
});

layer 弹框

// 显示弹框
function showDialog(text, icon, callback) {
  layer.open({
    time: 1500,
    anim: 4,
    offset: 't',
    icon: icon,
    content: text,
    btn: false,
    title: false,
    closeBtn: 0,
    end: function () {
      callback && callback();
    }
  });
});

轻便用户头像生成

// 引入对应的库
const crypto = require('crypto');
const identicon = require('identicon.js');

// 当用户注册时,根据用户的用户名生成随机头像
let hash = crypto.createHash('md5');
hash.update(username);
let imgData = new identicon(hash.digest('hex').toString());
let imgUrl = 'data:/image/png;base64,'+imgData;

orm表单提交的没相当

当使用form表单提交一些代码的时候,会产出浏览器拦截的现象,原因是:浏览器误认为客户拓展xss攻击。所以啊解决那几个主题素材也很简单,正是对交付的剧情开始展览base6肆或然此外花样的编码,在劳务器端实行解码,就能够化解。

源码地址:

你大概感兴趣的篇章:

  • 从零上学node.js之利用express搭建简易论坛(7)
  • Node.js+jade抓取博客全体小说生成静态html文件的实例
  • 运用Vue.js+Node.js+MongoDB完结1个博客系统(附源码)
  • nodejs个人博客开垦第玖步
    后台登入
  • nodejs个人博客开辟第5步
    数据分页
  • nodejs个人博客开拓第四步
    分配数据
  • nodejs个人博客开荒第四步
    数据模型
  • nodejs个人博客开辟第二步
    载入页面
  • nodejs个人博客开拓第2步
    入口文件
  • nodejs个人博客开拓第3步
    筹算干活
  • node.js实现博客小爬虫的实例代码
  • [将无偿开始展览到底]在亚马逊(Amazon)的一年无偿服务器上安装Node.JS,
    NPM和OurJS博客
  • node+koa贰+mysql+bootstrap搭建3个前端论坛

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有