《node.js实战》第七章 (7.1—7.2.3) connect 自带的中间件

connect强大之处在于它自带的中间件,它可以满足web开发的常见需求,比如:

中间件组件介绍
cookieParser()为后续中间件提供req.cookies和req.signedCookies
bodyParser()为后续中间件提供req.body和req.files
limit()基于给定字节长度限制请求主体的大小,必须用在bodyParser中间件之前
query()为后续中间件提供req.query
logger()将HTTP请求的信息输出到stdout或日志文件之类的流中
favicon()响应/favicon.ico HTTP请求。通常放在中间件logger前面,这样它就不会出现在你的日志文件中了
methodOverride()可以替不能使用正确请求方法的浏览器仿造req.method,依赖于bodyParser
vhost()根据指定的主机名使用给定的中间件和/或HTTP服务器实例
session()为用户设置一个HTTP会话,并提供一个可以跨越请求的持久化req.session对象。依赖于cookieParser
basicAuth()为程序提供HTTP基本认证
csrf()防止HTTP表单中的跨站请求伪造攻击,依赖于session
errorHandler()当出现错误时把堆栈跟踪信息返回给客户端。在开发时很实用,不过不要用在生产环境中
static()把指定目录中的文件发给HTTP客户端。跟Connect的挂载功能配合得很好
compress()用gzip压缩优化HTTP响应
directory()为HTTP客户端提供目录清单服务,基于客户端的Accept请求头提供经过优化的结果

7.1解析 cookie,请求主体和查询字符串的中间件

cookieParser() 解析HTTP cookie

cookieParser() 可以解析常规cookie,签名cookie和JSON cookie。

2.常规cookie

需要安装 cookie-parser这个包,其中"lalalala"是签名密钥

const connect = require('connect');
const cookieParser = require('cookie-parser');

var app = connect()
    .use(cookieParser('lalalala'))
    .use(function (req, res) {
        console.log(req.cookies);
        console.log(req.signedCookies);
        res.end('hello\n');
    }).listen(3000);

4.JSON cookie

JSON cookie带有前缀j 告诉connect它是一个串行化的JSON。

...
res.setHeader('set-cookie','bar=j:{"foo":"bar"}');
...

7.1.2 bodyParser() 解析请求主体

如果只是想解析x-www-form-urlencoded,仅仅在中间件使用bodyParser即可。

const bodyParser = require('body-parser');
const fs = require('fs');

var app = connect()
    .use(bodyParser.urlencoded({
        extended: false
    }))

    .use(function (req, res, next) {
        console.log(req.body);
    })
    .listen(3000);

解析application/json需要加载json()中间件:

app.use(bodyParser.json());

其中使用了bodyParser.urlencoded函数

  • extended: false:表示使用系统模块querystring来处理,也是官方推荐的
  • extended: true:表示使用第三方模块qs来处理
  • 从功能性来讲,qs比querystring要更强大,所以这里可以根据项目的实际需求来考虑

7.1.3 limit() 请求主体限制

需要限制请求主体的大小,避免大文件拖住服务器。


7.1.4 query() 查询字符串解析

需要引用connect-query解析query

下面这个小程序接收query并且发送回去

const query = require('connect-query');
var app = connect()

    .use(bodyParser.urlencoded({
        extended: false
    }))

    .use(query())

    .use((req,res,next)=>{
        res.end(JSON.stringify(req.query));
    })

app.listen(3000);

 7.2实现web程序核心功能的中间件

 7.2.1 logger()记录请求

1.基本用法

直接调用logger即可。

const logger = require("connect-logger");

var app = connect()

    .use(logger())
    
app.listen(3000);

 2.定制日志格式

使用%method格式,和书中有些许差异

.use(logger({ format: `%date %method %url`}))

 7.2.3 methodOverride 伪造HTTP方法

1.基本用法

X-HTTP-Method-Override是一个非标准的http头,他会根据这个头的值修改HTTP谓词

app.use(methodOverride("X-HTTP-Method-Override"))
//这样设置一个中间件

在postman这样设置methodOverride就会把请求改成PUT

 

const methodOverride = require('method-override');

var app = connect()

app.use(methodOverride("X-HTTP-Method-Override"))

    .use(logger())
    .use(edit)
    .use(update)

app.listen(3000);

//上传html
function edit(req, res, next) {
    if ('GET' != req.method) return next();
    res.setHeader('content-type', 'text/html');
    res.write('<form method="POST" action="./resource">');
    res.write('<input type="text" name="user" value="Tobi"/>');
    res.write('<input type="submit" value="update">');
    res.write("</form>");
    res.end();
}

//通过httml谓语PUT解析
function update(req, res, next) {
    if ('PUT' != req.method) return next();
    console.log(1);
    console.log(req.body);
    res.end("ok了家人们");
}

还有另一种方法:自定义函数判断

...
    app.use(methodOverride(function (req, res) {
        console.log(req.body);
        //判断_method是否存在
        if (req.body && typeof req.body === 'object' && '_method' in req.body) {
            // look in urlencoded POST bodies and delete it
            var method = req.body._method
            delete req.body._method
            存在就返回value
            return method
        }
    }))
  
...

function edit(req, res, next) {
    if ('GET' != req.method) return next();
    res.setHeader('content-type', 'text/html');
    res.write('<form method="POST" action="./resource">');
    //设置type = hidden name="_method" value = "PUT"
    //就会把method设置为PUT了
    res.write('<input type="hidden" name="_method" value="PUT"/>');
    res.write('<input type="text" name="user" value="Tobi"/>');
    res.write('<input type="submit" value="update">');
    res.write("</form>");
    res.end();
}

2.访问原始的req.method

console.log(req.methodOverride);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值