Express知识梳理

  1. 1. Express
    1. 1.1. 基本路由
    2. 1.2. Express静态服务API
    3. 1.3. 在Express中配置使用art-templete模板引擎
      1. 1.3.1. 在Express中获取表单请求数据
      2. 1.3.2. 获取get请求数据:
      3. 1.3.3. 获取post请求数据:
    4. 1.4. 在Express中配置使用express-session插件操作
  2. 2. Express中间件
    1. 2.1. 中间件的概念
    2. 2.2. 中间件的分类:
      1. 2.2.1. 应用程序级别的中间件
      2. 2.2.2. 关心请求路径和请求方法的中间件:
      3. 2.2.3. 路由级别的中间件
      4. 2.2.4. 严格匹配请求路径和请求方法的中间件
      5. 2.2.5. 总结
    3. 2.3. 错误处理中间件
    4. 2.4. 内置中间件
    5. 2.5. 第三方中间件

Express

原生的http在某些方面表现不足以应对我们的开发需求,所以就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码高度统一。

在node中有很多web开发框架。主要学习express

  • http://expressjs.com/,其中主要封装的是http。

  • ```javascript
    // 1 安装
    // 2 引包
    var express = require(‘express’);
    // 3 创建服务器应用程序
    // 也就是原来的http.createServer();
    var app = express();

    // 公开指定目录
    // 只要通过这样做了,就可以通过/public/xx的方式来访问public目录中的所有资源
    // 在Express中开放资源就是一个API的事
    app.use(‘/public/‘,express.static(‘/public/‘));

    //模板引擎在Express中开放模板也是一个API的事

    // 当服务器收到get请求 / 的时候,执行回调处理函数
    app.get(‘/‘,function(req,res){
    res.send(‘hello express’);
    })

    // 相当于server.listen
    app.listen(3000,function(){
    console.log(‘app is runing at port 3000’);
    })

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    ## hello world:

    ```javascript
    // 引入express
    var express = require('express');

    // 1. 创建app
    var app = express();

    // 2.
    app.get('/',function(req,res){
    // 1
    // res.write('Hello');
    // res.write('World');
    // res.end()

    // 2
    // res.end('hello world');

    // 3
    res.send('hello world');
    })

    app.listen(3000,function(){
    console.log('express app is runing...');
    })

基本路由

路由:

  • 请求方法
  • 请求路径
  • 请求处理函数

get:

1
2
3
4
//当你以get方法请求/的时候,执行对应的处理函数
app.get('/',function(req,res){
res.send('hello world');
})

post:

1
2
3
4
//当你以post方法请求/的时候,执行对应的处理函数
app.post('/',function(req,res){
res.send('hello world');
})

Express静态服务API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// app.use不仅仅是用来处理静态资源的,还可以做很多工作(body-parser的配置)
app.use(express.static('public'));

app.use(express.static('files'));

app.use('/stataic',express.static('public'));
// 引入express
var express = require('express');

// 创建app
var app = express();

// 开放静态资源
// 1.当以/public/开头的时候,去./public/目录中找对应资源
// 访问:http://127.0.0.1:3000/public/login.html
app.use('/public/',express.static('./public/'));

// 2.当省略第一个参数的时候,可以通过省略/public的方式来访问
// 访问:http://127.0.0.1:3000/login.html
// app.use(express.static('./public/'));

// 3.访问:http://127.0.0.1:3000/a/login.html
// a相当于public的别名
// app.use('/a/',express.static('./public/'));

//
app.get('/',function(req,res){
res.end('hello world');
});

app.listen(3000,function(){
console.log('express app is runing...');
});

在Express中配置使用art-templete模板引擎

  • art-template官方文档

  • 在node中,有很多第三方模板引擎都可以使用,不是只有art-template,还有ejs,jade(pug),handlebars,nunjucks

安装:

1
2
3
4
5
npm install --save art-template
npm install --save express-art-template

//两个一起安装
npm i --save art-template express-art-template

配置:

1
app.engine('html', require('express-art-template'));

使用:

1
2
3
4
5
6
app.get('/',function(req,res){
// express默认会去views目录找index.html
res.render('index.html',{
title:'hello world'
});
})

如果希望修改默认的views视图渲染存储目录,可以:

1
2
// 第一个参数views千万不要写错
app.set('views',目录路径);

在Express中获取表单请求数据

获取get请求数据:

Express内置了一个api,可以直接通过req.query来获取数据

1
2
3
// 通过requery方法获取用户输入的数据
// req.query只能拿到get请求的数据
var comment = req.query;

获取post请求数据:

在Express中没有内置获取表单post请求体的api,这里我们需要使用一个第三方包body-parser来获取数据。

安装:

1
npm install --save body-parser;

配置:

// 配置解析表单 POST 请求体插件(注意:一定要在 app.use(router) 之前 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var express = require('express')
// 引包
var bodyParser = require('body-parser')

var app = express()

// 配置body-parser
// 只要加入这个配置,则在req请求对象上会多出来一个属性:body
// 也就是说可以直接通过req.body来获取表单post请求数据
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

使用:

1
2
3
4
5
6
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
// 可以通过req.body来获取表单请求数据
res.end(JSON.stringify(req.body, null, 2))
})

在Express中配置使用express-session插件操作

参考文档:https://github.com/expressjs/session

安装:

1
npm install express-session

配置:

1
2
3
4
5
6
7
8
9
10
11
//该插件会为req请求对象添加一个成员:req.session默认是一个对象
//这是最简单的配置方式
//Session是基于Cookie实现的
app.use(session({
//配置加密字符串,他会在原有的基础上和字符串拼接起来去加密
//目的是为了增加安全性,防止客户端恶意伪造
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,//无论是否适用Session,都默认直接分配一把钥匙
cookie: { secure: true }
}))

使用:

1
2
3
4
5
6
7
8
9
10
11
12
// 读
//添加Session数据
//session就是一个对象
req.session.foo = 'bar';

//写
//获取session数据
req.session.foo

//删
req.session.foo = null;
delete req.session.foo

提示:

默认Session数据时内存储数据,服务器一旦重启,真正的生产环境会把Session进行持久化存储。

Express中间件

中间件的概念

参考文档:http://expressjs.com/en/guide/using-middleware.html

中间件:把很复杂的事情分割成单个,然后依次有条理的执行。就是一个中间处理环节,有输入,有输出。

说的通俗易懂点儿,中间件就是一个(从请求到响应调用的方法)方法。

把数据从请求到响应分步骤来处理,每一个步骤都是一个中间处理环节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var http = require('http');
var url = require('url');

var cookie = require('./expressPtoject/cookie');
var query = require('./expressPtoject/query');
var postBody = require('./expressPtoject/post-body');

var server = http.createServer(function(){
// 解析请求地址中的get参数
// var obj = url.parse(req.url,true);
// req.query = obj.query;
query(req,res); //中间件

// 解析请求地址中的post参数
req.body = {
foo:'bar'
}
});

if(req.url === 'xxx'){
// 处理请求
...
}

server.listen(3000,function(){
console.log('3000 runing...');
});

同一个请求对象所经过的中间件都是同一个请求对象和响应对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var express = require('express');
var app = express();
app.get('/abc',function(req,res,next){
// 同一个请求的req和res是一样的,
// 可以前面存储下面调用
console.log('/abc');
// req.foo = 'bar';
req.body = {
name:'xiaoxiao',
age:18
}
next();
});
app.get('/abc',function(req,res,next){
// console.log(req.foo);
console.log(req.body);
console.log('/abc');
});
app.listen(3000, function() {
console.log('app is running at port 3000.');
});

中间件的分类:

应用程序级别的中间件

万能匹配(不关心任何请求路径和请求方法的中间件):

1
2
3
4
app.use(function(req,res,next){
console.log('Time',Date.now());
next();
});

关心请求路径和请求方法的中间件:

1
2
3
4
app.use('/a',function(req,res,next){
console.log('Time',Date.now());
next();
});

路由级别的中间件

严格匹配请求路径和请求方法的中间件

get:

1
2
3
app.get('/',function(req,res){
res.send('get');
});

post:

1
2
3
app.post('/a',function(req,res){
res.send('post');
});

put:

1
2
3
app.put('/user',function(req,res){
res.send('put');
});

delete:

1
2
3
app.delete('/delete',function(req,res){
res.send('delete');
});

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
var express = require('express');
var app = express();

// 中间件:处理请求,本质就是个函数
// 在express中,对中间件有几种分类

// 1 不关心任何请求路径和请求方法的中间件
// 也就是说任何请求都会进入这个中间件
// 中间件本身是一个方法,该方法接收三个参数
// Request 请求对象
// Response 响应对象
// next 下一个中间件
// // 全局匹配中间件
// app.use(function(req, res, next) {
// console.log('1');
// // 当一个请求进入中间件后
// // 如果需要请求另外一个方法则需要使用next()方法
// next();
// // next是一个方法,用来调用下一个中间件
// // 注意:next()方法调用下一个方法的时候,也会匹配(不是调用紧挨着的哪一个)
// });
// app.use(function(req, res, next) {
// console.log('2');
// });

// // 2 关心请求路径的中间件
// // 以/xxx开头的中间件
// app.use('/a',function(req, res, next) {
// console.log(req.url);
// });

// 3 严格匹配请求方法和请求路径的中间件
app.get('/',function(){
console.log('/');
});
app.post('/a',function(){
console.log('/a');
});

app.listen(3000, function() {
console.log('app is running at port 3000.');
});

错误处理中间件

1
2
3
4
app.use(function(err,req,res,next){
console.error(err,stack);
res.status(500).send('Something broke');
});

配置使用404中间件:

1
2
3
app.use(function(req,res){
res.render('404.html');
});

配置全局错误处理中间件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app.get('/a', function(req, res, next) {
fs.readFile('.a/bc', funtion() {
if (err) {
// 当调用next()传参后,则直接进入到全局错误处理中间件方法中
// 当发生全局错误的时候,我们可以调用next传递错误对象
// 然后被全局错误处理中间件匹配到并进行处理
next(err);
}
})
});
//全局错误处理中间件
app.use(function(err,req,res,next){
res.status(500).json({
err_code:500,
message:err.message
});
});

内置中间件

第三方中间件

参考文档:http://expressjs.com/en/resources/middleware.html

  • body-parser
  • compression
  • cookie-parser
  • mogran
  • response-time
  • server-static
  • session