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

来源:互联网 发布:广东玉米数据网账号 编辑:程序博客网 时间:2024/06/10 11:24

个人总结,仅供参考,详细内容请 参考官方教程:
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 -gexpress -hexpress -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 pagerouter.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 --savevar 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.jsvar 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、Sessionapp.get('/', function(req, res) {  console.log("Cookies: ", req.cookies);  console.log("Session: ", req.session);})

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

配置session到mongodb

//app.jsvar mongoose = require('mongoose');  , MongoStore = require('connect-mongo')(express);// Basic usagemongoose.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.jsrouter.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引擎

1 0
原创粉丝点击