目录
前言body-parser获取POST请求安装使用 自定义中间件实现POST参数验证定制中间件 使用必填参数验证选填参数 总结前言
在编写接口时,往往会用到POST请求,但凡是带参数的请求,都少不了参数的合法性验证,比如是否包含参数字段,或者参数是否在合法范围内。
这些验证是常见的,且可复用的,所以今天编写一个中间件来验证POST请求的参数。
body-parser获取POST请求
在验证POST字段之前,我们首先得获取POST请求的请求体对象(即键值对们),才能进行合法性判断。所以我们引入body-parser包,获取POST请求。
安装
使用node的包管理工具npm可以快速安装body-parser
npm install body-parser
如果报错找不到body-parser,那么请在要运行的js文件的目录下,使用link命令:
npm link body-parser
使用
在处理请求的中间件注册之前,注册body-parser即可
var express = require('express');var app = express();var bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended: false }));// 解析POSTapp.use(bodyParser.json());// 变成json对象
然后我们可以在req.body[键名称]
中获取对应的值,以完成对post请求的解析。下面是body-parser的示例代码,我们接收并回显POST请求的键值对们:
var express = require('express');var app = express();var bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended: false }));app.use(bodyParser.json());var middleware = function(req, res, next) {var ret = "";for(key in req.body) {ret += key + " - " + req.body[key] + "\n";}res.end(ret);};app.post('/', middleware);app.listen(8888);console.log("开始运行于 localhost:8888");
POSTMAN测试结果
自定义中间件实现POST参数验证
上文介绍了如何获取POST参数,接下来我们对参数进行验证,验证主要从三个方面入手:
请求是否携带必填参数参数值是否在合法范围内选填参数是否具有默认值
假设我们知道参数的
参数名 param合法范围 legalList默认值defaultValue(选填参数不填则为默认值)
那么我们可以编写以下的函数,实现过滤功能:
function(req, res, next) {var param = "name";var legalList = ["zhang3", "lee4", "wang5"];var defaultValue = null;// 为null则必填// 如果未填参数if(req.body[param] === undefined) {// 参数如果必填if(defaultValue == null) {res.end(JSON.stringify({"state": 777,"message": "参数错误 必填参数 " + param + " 缺失"}));return;}// 选填则帮忙填上req.body[param] = defaultValue;}// 如果有参数范围 检验参数是否合法if(legalList && !legalList.includes(req.body[param])) {res.end(JSON.stringify({"state": 888,"message": "参数错误 参数 " + param + " 值非法"}));return;}next(); // 校验正确则next}
但是这么做不方便代码的复用,因为除了参数名,合法范围,默认值
以外,其他的代码都是相同的,那么我们可以定制一个函数,传入参数名,合法范围,默认值
,返回定制的过滤函数。
定制中间件
利用JavaScript闭包的特性,定制的中间件函数可以访问传入的参数名,合法范围,默认值
,从而返回定制的中间件函数即可。
function checker(param, legalList, defaultValue) {return function(req, res, next) {// 如果未填参数if(req.body[param] === undefined) {// 参数如果必填if(defaultValue == null) {res.end(JSON.stringify({"state": 777,"message": "参数错误 必填参数 " + param + " 缺失"}));return;}// 选填则帮忙填上req.body[param] = defaultValue;}// 如果有参数范围 检验参数是否合法if(legalList && !legalList.includes(req.body[param])) {res.end(JSON.stringify({"state": 888,"message": "参数错误 参数 " + param + " 值非法"}));return;}next(); // 校验正确则next}}
使用
使用刚刚编写的定制函数,我们需要传入三个变量:
参数名 param合法范围 legalList默认值defaultValue(选填参数不填则为默认值)
其中param为必填,legalList和defaultVaule如果为null,表示参数范围不限 / 参数必填
必填参数验证
假设必填参数为name,合法范围为["zhang3", "lee4", "wang5"]
,因为是必填,所以没有默认值,我们defaultValue填null即可。
var express = require('express');var app = express();var bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended: false }));app.use(bodyParser.json());function checker() {checker函数上文有 就不重复粘贴了}// 参数验证 app.post('/', checker("name", ["zhang3", "lee4", "wang5"], null));app.listen(8888);
postman测试:我们没填name字段,就报错了
我们填一个非法的值试一下,可以看到只要不再范围内,就报错。
选填参数
选填参数我们传入默认值不为null即可,默认值为zhang3
,这里我们还是:选填参数为name,合法范围为["zhang3", "lee4", "wang5"]
。然后我们返回name参数的值,看看默认值是不是我们预想的那样
var express = require('express');var app = express();var bodyParser = require('body-parser');app.use(bodyParser.urlencoded({extended: false }));app.use(bodyParser.json());function checker() {checker函数上文有 就不重复粘贴了}// 参数默认值验证app.post('/', checker("name", ["zhang3", "lee4", "wang5"], "zhang3"));app.post('/', function(req, res, next) {res.end(req.body["name"]);});app.listen(8888);
可以看到,没填的参数,中间件自动帮我们填了,还是挺方便的
总结
中间件避免了代码的重复使用,因为同样是过滤POST请求,只需要很少的改动,就能适应不同的参数,那么我们传入少量的变量就可以定制一个中间件了。
下面总结一下定制函数的形参如果为null,那么他们表示的意义: