We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文以 Express 框架为基础,讲诉如何通过一个中间件来检测 Express 路由中传输的参数是否合法。
几乎对于任何应用,前后端都需要进行传输数据。不管是通过 HTTP 请求的 POST 方法还是 GET 方法,数据校验都是必要的操作。
对于大部分 API 来说,可能只需要判断传入的参数是否为 undefined 或 null,所以这个时候,为了减少重复代码,我们可以写一个简单的中间件来处理路由中的参数。
这个中间件的需求如下:
最终写出来的处理参数的模块:
/** * 检测路由中的参数 * @method checkParameters * @param {object} req http请求 * @param {object} res http响应 * @param {Function} next * @param {[type]} special 特殊参数, * 格式: [{eval: 'req.query.id>0', key:'id', type: 'query'}] * key 属性的值必须和eval中对应,且type只能是 query/params/body * @return {object} 若参数错误,直接返回json到前端;正确,则next() */ function checkParameters(req, res, next, special) { // console.log('params: ', req.params); // console.log('body: ', req.body); // console.log('query: ', req.query); console.log('specialParams: ', typeof special); // 判断是否传入第四个参数 if (Array.isArray(special)) { // 判断特殊参数 for (let i = 0; i < special.length; i++) { // console.log('special[i]: ', special[i]); // console.log('special[i] eval: ', special[i].hasOwnProperty('eval')); // console.log('special[i] key: ', special[i].hasOwnProperty('key')); // console.log('special[i] type: ', special[i].hasOwnProperty('type')); // 判断是否具有 eval, key, type 三个参数 if (! (special[i].hasOwnProperty('eval') && special[i].hasOwnProperty('key') && special[i].hasOwnProperty('type'))) { return res.json({ code: 90001, msg: '检测参数属否正确时,传入的特殊参数格式不完全', detail: special }); } // 判断 eval, key, type 三个参数是否为 undefined if ( !(typeof special[i]['eval'] !== undefined && typeof special[i]['key'] !== undefined && typeof special[i]['type'] !== undefined)) { return res.json({ code: 90002, msg: '检测参数属否正确时,传入的特殊参数为 undefined', detail: special }); } const evalString = special[i]['eval']; const type = special[i]['type']; const key = special[i]['key']; // 判断 key 和 eval 是否匹配 console.log('length: ', evalString .split('req.' + type + '.' + key) .length); const length = evalString.split('req.' + type + '.' + key).length; if (length < 1) { return res.json({ code: 90003, msg: '检测参数属否正确时,传入的特殊参数为格式不正确', detail: special }); } // 执行 eval if (!eval(evalString)) { return res.json({ code: 90004, msg: '检测参数属否正确时,参数不匹配传入的条件 ' + evalString, detail: special, parameters: req[type] }); } // 从普通参数中删除特殊参数 // console.log('delete: ', req[type][key]); delete req[type][key]; } } const params = req.params; // 去掉 req.params 中 {'0': '', ...} 这一项 delete params['0']; // console.log('params: ', params); const body = req.body; const query = req.query; const common = Object.assign(params, body, query); console.log('common: ', common); // 检测参数属否为undefined for (let i in common) { if (typeof common[i] === 'undefined') { return res.json({ code: 90005, msg: '检测参数属否正确时,' + i + ' 参数为undefined', detail: common }); } // 检测参数属否为null if (common[i] === null) { return res.json({ code: 90006, msg: '检测参数属否正确时,' + i + ' 参数为null', detail: common }); } // 检测参数是否为空字符串 '' if (common[i] === '') { return res.json({ code: 90007, msg: '检测参数属否正确时,' + i + ' 参数为空字符串', detail: common }); } // 检测参数是否为空数组 [] if (common[i] === '') { return res.json({ code: 90008, msg: '检测参数属否正确时,' + i + ' 参数为空数组', detail: common }); } } return next(); } module.exports = checkParameters;
1. 特殊参数的处理
这个模块,首先对特殊参数做处理。special 这个参数是一个数组,格式如下:
special
[{ eval: 'parseInt(req.query.id) > 1 && parseInt(req.query.id) < 10', key: 'id', type: 'query' }, { eval: 'parseInt(req.query.age) === 11', key: 'age', type: 'query' }]
key 属性的值必须和eval中对应,且type只能是 query/params/body。
eval()
key
2. 普通参数处理
处理完毕特殊参数后,就需要处理普通参数。普通参数只需要满足:
undefined
null
''
[]
普通参数,即 req.body req.params req.query 中的所有非特殊参数。
req.body
req.params
req.query
除了在判断特殊参数的时候,需要 delete 特殊参数,还需要 delete req.params['0']。因为对于 req.params,当 URL 没有 path 部分的时候,req.params['0'] 为 ''。
delete req.params['0']
path
req.params['0']
处理完毕之后,若所有参数都合法,则返回 next()。
next()
1. 创建没有挂载路径的中间件
首先在 Express 项目入口文件,创建一个参数处理中间件:
// app.js const checkParameters = require('./checkParameters'); // ... app.use(function(req, res, next) { checkParameters(req, res, next); });
注意这里的 app.use() 需要放在创建具体路由中间件如app.use('/', index) 之前。
app.use()
app.use('/', index)
当 Express 接收到 HTTP 请求后,首先该中间件会检测参数是否合法(只判断是否为 null 或 undefine 或 '' 或 [])。如果不合法,则直接返回;如果合法,则程序继续执行,由匹配该请求路径的路由继续完成该请求。
2. 创建挂载路径的中间件
如果需要对某个路由的特殊参数做处理,则需要创建一个挂载路径的中间件。
比如为们要判断 /index 路由的 GET 请求中的 id 参数,其中 id 的取值范围是 1-100,URL 形式如 http://localhost:3000/index?id=10,则可以这样使用该模块:
/index
id
http://localhost:3000/index?id=10
// index.js const checkParameters = require('./checkParameters'); // 挂载路径的中间件 router.get('/index', function(req, res, next) { const special = { eval: 'parseInt(req.query.id) >= 1 && parseInt(req.query.id) <= 100', key: 'id', type: 'query' }; checkParameters(req, res, next, special); }); // 正常逻辑处理 router.get('/index', function(req, res, next) { // 正常逻辑 });
当 Express 接收到一个 HTTP 请求的时候,首先还是没有挂载路径的中间件先处理请求,检测参数;然后该挂载路径的中间件再检测参数;最后才执行正常处理逻辑。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
本文以 Express 框架为基础,讲诉如何通过一个中间件来检测 Express 路由中传输的参数是否合法。
几乎对于任何应用,前后端都需要进行传输数据。不管是通过 HTTP 请求的 POST 方法还是 GET 方法,数据校验都是必要的操作。
对于大部分 API 来说,可能只需要判断传入的参数是否为 undefined 或 null,所以这个时候,为了减少重复代码,我们可以写一个简单的中间件来处理路由中的参数。
这个中间件的需求如下:
最终写出来的处理参数的模块:
函数详解
1. 特殊参数的处理
这个模块,首先对特殊参数做处理。
special
这个参数是一个数组,格式如下:key 属性的值必须和eval中对应,且type只能是 query/params/body。
eval()
函数来执行这个表达式。key
表示参数属性名,type 表示是通过何种方式传递的参数,如 query/params/body。2. 普通参数处理
处理完毕特殊参数后,就需要处理普通参数。普通参数只需要满足:
undefined
null
''
[]
普通参数,即
req.body
req.params
req.query
中的所有非特殊参数。除了在判断特殊参数的时候,需要 delete 特殊参数,还需要
delete req.params['0']
。因为对于req.params
,当 URL 没有path
部分的时候,req.params['0']
为''
。处理完毕之后,若所有参数都合法,则返回
next()
。模块使用
1. 创建没有挂载路径的中间件
首先在 Express 项目入口文件,创建一个参数处理中间件:
注意这里的
app.use()
需要放在创建具体路由中间件如app.use('/', index)
之前。当 Express 接收到 HTTP 请求后,首先该中间件会检测参数是否合法(只判断是否为 null 或 undefine 或 '' 或 [])。如果不合法,则直接返回;如果合法,则程序继续执行,由匹配该请求路径的路由继续完成该请求。
2. 创建挂载路径的中间件
如果需要对某个路由的特殊参数做处理,则需要创建一个挂载路径的中间件。
比如为们要判断
/index
路由的 GET 请求中的id
参数,其中id
的取值范围是 1-100,URL 形式如http://localhost:3000/index?id=10
,则可以这样使用该模块:当 Express 接收到一个 HTTP 请求的时候,首先还是没有挂载路径的中间件先处理请求,检测参数;然后该挂载路径的中间件再检测参数;最后才执行正常处理逻辑。
The text was updated successfully, but these errors were encountered: