读书笔记——node开发指南——博客系统express4源码

个人总结,仅供参考,详细内容请 参考官方教程:
github项目源代码:代码链接
终端下载git clone https://github.com/RobinsonKO/node-blog.git
推荐文章:git详细入门攻略

1、环境搭配与项目创建

node.js

1、模块机制

  • CommonJS规范出发点:
    -JavaScript没有模块系统
    - 标准库少。ECMAScript仅定义了部分核心库,对于文件系统,I/O流等常见需求没有标准API
    - 没有标准接口。没用定义Web服务器或者数据库的标准统一接口
    - 缺乏包管理系统。没有自动加载和安装依赖的能力
  • 模块规范

2、异步I/O

3、事件与回调函数

Express

1、创建项目

参考:创建一个项目,项目整体框架介绍

npm istall express-generator -g

express -h
express -e blog

2、使用中间件

一个express项目中包含以下几类中间件,熟悉这几类中间件之后,在去分析app.js中的内容就清晰多了。

  • 应用层中间件
  • 路由层中间件
  • 错误处理层中间件
  • 内建中间件
  • 第三方中间件

应用层中间件是通过app实例对象使用app.use()、app.METHOD()使用的,例如:

var app = express();
app.use(function (req, res, next) {
   console.log('Time: ',Date.now();
   next();
 };
app.get('/user, function(req, res ,next) {
   res.send('USER');
 };

路由层中间件和应用层中间件类似,只是通过Router实例对象使用use()、METHOD()方法,例如:

var express = require('express');
var Router = express.Router();
router.use(function (req, res, next) {
   console.log('Time: ',Date.now();
   next();
 };
router.get('/user, function(req, res ,next) {
   res.send('USER');
 };
  • router和app的区别:
    Use the express.Router class to create modular, mountable route handlers. A Router instance is a complete middleware and routing system; for this reason, it is often referred to as a “mini-app”.

错误处理中间件必须包含4个参数,即使不使用next对象,例如:

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});
  • 传递给next()的任何参数(除了 route),Express都会把它当做当前请求出错,之后会跳过后续的非错误处理路由和中间件,如果没有自定义的错误处理,就会调用Express默认的错误处理函数
  • next(route):跳过同一个路由当中后续回调函数,例如:
router.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next router
  if (req.params.id == 0) next('route');
  // otherwise pass control to the next middleware function in this stack
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});
// handler for the /user/:id path, which renders a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

从4.x版本之后,Express就不在依赖Connect,除了express.static之外,其他的中间件都作为独立的第三方中间件使用,第三方中间件的使用方法为,例如使用cookie-parser

npm install cookie-parser --save
var CookiePaser = require('cookie-parser);
var app = express();
app.use(CookieParser());

建议独自查看:官方教程

2、连接数据库与基本操作

  • mongodb数据库(作为本地服务?)

  • node.js开发之express4.0使用mongoose连接mongodb

  • MongoDB基本管理命令
  • Mongoose学习参考文档——基础篇
    关于Schema、Model、Entity的说明非常精辟
  • MVC中的M

3、配置会话

什么是Cookie、Session

  • Cookie:HTTP是无状态的协议,但现实中的业务处理需要一定的状态,否者就无法区分不同的用户。比如说无需登录京东就可以添加购物车,你每一次添加的物品(多次请求)都到了同一个购物车。这就需要使用Cookie(存在于报文中)来标识和认证同一个账户。(前后端都可以操作Cookie)
  • Cookie在浏览器和服务器的协作处理分下面几步
    -服务器向浏览器发送Cookie
    -浏览器将Cookie保存
    -之后每次浏览器都会想服务器发送Cookie
  • Session:由于在前后端都可以操作Cookie,所以有时使用Cookie是不安全的。比如需要更具Cookie中的isVIP字段来判断业务逻辑,但是前端可以篡改它来达到伪造的目的。而Session只保存在后端,对前端不可见,因此对于数据敏感的操作,就需要用到Session。(Session有效期限短)
  • 基于Cookie来实现用户与数据的映射:服务器生成Session口令,传递Cookie,通过Cookie口令与Session口令来实现用户与数据的映射。一旦篡改了Cookie口令,就无法完成映射。并且Session口令过期时间短,之后再生成新的口令,这也是为什么登陆京东一段时间不操作就需要重新登陆。

配置本地session

//app.js
var express      = require('express')
  , cookieParser = require('cookie-parser')
  , session      = require('express-session')
  , app = express()

app.use(cookieParser()) // required before session.
app.use(session({ 
      secret: 'keyboard cat',
      key: 'sid', 
      cookie: { secure: true, maxAge: 60000 }
      })
    )

Session数据并不是保存在Cookie中,反而用到了Cookie,所以必须提前使用[cookie-parser]

Options

  • key - cookie name defaulting to connect.sid.
  • store - session store instance.
  • secret - session cookie is signed with this secret to prevent tampering.
  • proxy - trust the reverse proxy when setting secure cookies (via “x-forwarded-proto”).
  • cookie - session cookie settings, defaulting to { path: '/', httpOnly: true, secure: false, maxAge: null }
// routes/index.js   打印出Cookie、Session
app.get('/', function(req, res) {
  console.log("Cookies: ", req.cookies);
  console.log("Session: ", req.session);
})

通过req.cookies 、 req.session 获取相应cookie,session信息

配置session到mongodb

//app.js
var mongoose = require('mongoose');
  , MongoStore = require('connect-mongo')(express);

// Basic usage
mongoose.connect('mongodb://localhost/blog');

app.use(session({
    store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

使用req.flash()

//app.js
 var flash = require('connect-flash');

 app.use(express.cookieParser('keyboard cat'));
 app.use(session({
    store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
  app.use(flash());

  // routes/index.js   测试
  router.post('/reg', function(req, res) {
  //检查用户两次输入的口令是否一致
  if (req.body['password-repeat'] != req.body['password']) {
    req.flash('error','两次输入密码口令不一致');
    console.log("Session: ", req.session);//错误时,显示flash信息
    return res.redirect('/reg');
  }
  ...
 }
 /*  后台打印出的Session信息
 Session:  Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true },
  flash: { error: [ '两次输入的口令不一致' ] },
  user: null }
  */

flash保存住Session中,通过flash中的变量自会在用户当前和下一次请求中被访问,之后就会被删除,通常与重定位redirect一起使用,可以方便的实现页面的通知和错误信息显示

在项目中的使用

// routes/index.js
router.post('/reg', function(req, res) {
   ...
   req.session.user = UserEntity;
   ...
}

function checkLogin(req,res,next) {
  if (!req.session.user) {
    req.flash('error','未登录');
    return res.redirect('/login');
  }
  next();
}

通过把用户保存到Session中,来区分用户是否登录和区分不同用户

//  res.local 属性 把error等属性注册views层全局变量,生命周期为一次request请求,从而实现动态视图
app.use(function(req, res, next){
  console.log("Comes to DynamicHelper");
  res.locals.user = req.session.user;
  res.locals.post = req.session.post;
  var error = req.flash('error');
  res.locals.error = error.length ? error : null;

  var success = req.flash('success');
  res.locals.success = success.length ? success : null;
  next();
});
  • res.locals:
    An object that contains response local variables scoped to the request, and therefore available only to the view(s) rendered during that request / response cycle (if any). Otherwise, this property is identical to app.locals.
    This property is useful for exposing request-level information such as the request path name, authenticated user, user settings, and so on.

4、ejs引擎

你可能感兴趣的:(【js】)