网站备案怎么登陆,dwcc网站前台脚本怎么做音频,2019建设银行招聘网站,网络营销论文摘要文章目录 Restify简介1. Restify是什么#xff1f;2. 安装Restify3. 实现一个最简单的服务器 处理程序链1. 什么是处理程序链2. next()函数3. 三类处理程序链3.1. 通用预处理程序链#xff1a;pre3.2. 通用处理程序链#xff1a;use3.3. 路由处理程序链 4. 错误处理 插件1. … 文章目录 Restify简介1. Restify是什么2. 安装Restify3. 实现一个最简单的服务器 处理程序链1. 什么是处理程序链2. next()函数3. 三类处理程序链3.1. 通用预处理程序链pre3.2. 通用处理程序链use3.3. 路由处理程序链 4. 错误处理 插件1. pre插件1.1. context1.2. dedupeSlashes1.3. sanitizePath 2. use插件2.1. acceptParser2.2. queryParser2.3. bodyParser2.4. serveStatic 鉴权机制1. 基本使用2. token过期和刷新 Restify简介
1. Restify是什么
Restify是一个专注于RESTful API的nodejs框架。
2. 安装Restify
npm init -y
npm i restify -S3. 实现一个最简单的服务器
var restifyrequire(restify)
var serverrestify.createServer()server.get(/hello/:name,(req,res,next){res.send(hello req.params.name)return next()
})server.listen(8000,(){console.log(server.name)console.log(server.url)
})$ curl -is http://localhost:8000/hello/world
HTTP/1.1 200 OK
Server: restify
Content-Type: application/json
Content-Length: 13
Date: Sat, 20 Jan 2024 09:02:45 GMT
Connection: keep-alive
Keep-Alive: timeout5hello world处理程序链 1. 什么是处理程序链
所谓处理程序链是指一组处理程序按顺序依次执行。 如下定义了针对’/hello/:name’路由的一组路由处理程序链
server.get(/hello/:name,function(req,res,next){console.log(first step)return next() //程序链式执行的关键不可省略},function(req,res,next){console.log(second step)res.send(how are you!) //在一条处理链上只能向客户端返回一次数据。return next()},function(req,res,next){console.log(third step)return next()}
)2. next()函数
处理程序链中的每个程序执行之后都需要手工调用next()这将移动到链中的下一个函数继续执行。调用res.send()不会自动触发next()send()之后可能还要继续处理因此也需要手动调用next()。
正常情况下next()不需要任何参数。若由于某种原因条件需要提前终止程序链向后继续执行可调用next(false)。
next()也接受Error类型对象这将导致Restify向客户端发送错误状态码错误状态码根据Error类型进行推断Error类型为500NotFoundError类型为404。关于错误处理参见后文错误处理
server.get(/hello/:name,(req,res,next){if(req.params.name) return next(new Error(no name!)res.send(hello req.params.name)return next()
})3. 三类处理程序链
在Restify服务器中有三类处理程序链
pre 在路由之前的处理程序链use 在路由之后的处理程序链对所有路由都生效{httpVerb} 对特定路由执行的处理程序链见上例
3.1. 通用预处理程序链pre
pre对传入的所有请求都执行即便请求的路由未注册。这可以用于记录日志或在路由之前清理传入的请求。
server.pre(function(req,res,next){console.warn(run before route! 1)return next()},function(req,res,next){console.warn(run before route! 2)return next()}
)3.2. 通用处理程序链use
use对所有被匹配的路由都执行。
server.use(function(req,res,next){console.warn(run for all routers! 1)return next()},function(req,res,next){console.warn(run for all routers! 2)return next()}
)3.3. 路由处理程序链
Restify使用HTTP动词和参数来确定路由处理程序链。参数值可以通过req.params获取。
function send(req,res,next){res.send(hello req.params.name)return next()
}
server.post(/hello,function(req,res,next){res.send(201,Math.random().toString(36).substr(3,8))return next()
})
server.put(/hello,send)
server.get(/hello/:name,send)
server.del(/hello/:name,function(req,res,next){res.send(204)return next()
})路由可以指定的HTTP动词包括get、post、del、put、head、opts、patch。 4. 错误处理
Restify可以通过事件方式来处理错误。通过next(error)抛出错误事件并用on()函数为特定错误事件添加侦听器。 restify-errors模块封装了一组常见HTTP和REST错误的构造函数。
const errsrequire(restify-errors)server.get(/hello/:name,function(req,res,next){//找不到资源return next(new errs.NotFoundError())
})server.on(NotFound,function(req,res,err,callback){//不能调用res.send()因为现在处于错误处理上下文不在路由处理程序链中。//在此处可以记录错误日志或执行善后处理。//当完成错误处理后调用回调函数回到路由处理程序链Restify将根据错误类型自动发送包含错误代码的响应报文。return callback()
})常用的错误事件如下
400 BadDigestError405 BadMethodError500 InternalError409 InvalidArgumentError400 InvalidContentError401 InvalidCredentialsError400 InvalidHeaderError400 InvalidVersionError409 MissingParameterError403 NotAuthorizedError412 PreconditionFailedError400 RequestExpiredError429 RequestThrottledError404 ResourceNotFoundError406 WrongAcceptError
插件
restify.plugins模块中提供过了一系列有用的插件这些插件可以通过server.pre()或server.use()加载。
1. pre插件
pre类插件会在路由之前使用。
1.1. context
该插件给req添加了设置键值对req.set(key.val)和读取值req.get(key)方法。
server.pre(restify.plugins.pre.context())
server.get(/,function(req,res,next){req.set(myMessage,hello world)return next()},function(req,res,next){res.send(req.get(myMessage))return next()}
)1.2. dedupeSlashes
该插件会删除URL中重复斜杠比如会将请求/hello/abc转换为/hello/abc。
server.pre(restify.plugins.pre.dedupeSlashes())
server.get(/hello/:name,function(req,res,next){res.send(200)return next()
})1.3. sanitizePath
该插件修复URL比如会将/foo//bar//“转化为”/foo/bar
server.pre(restify.plugins.pre.sanitizePath())
server.get(/hello/:name,function(req,res,next){res.send(200)return next()
})2. use插件
use类插件会对所有路由生效。
2.1. acceptParser
解析Accept头确保服务器可以提供客户要求的内容。若请求一个无法处理的类型该插件会返回NotAcceptableError(406)错误。通过server.acceptable可获取restify服务器可接受的类型。 server.acceptable
[application/json,text/plain,application/octet-stream,application/javascript
]通常该插件都应该被加载
server.use(restify.plugins.acceptParser(server.acceptable))2.2. queryParser
解析HTTP查询字符串如/hello?nameabcjobdoctor。若使用该插件解析的内容在req.query中可用。 该插件接受一个选项参数mapParams可配置是否将req.query合并到req.params字段中req.params字段是针对/hello/:sex这类参数若将mapParams配置为true则类似/hello/male?nameabcjobdoctor这类路由解析后的req.query为。
...
server.use(restify.plugins.queryParser({mapParams:true}))
server.get(/foo/:sex,(req,res,next){res.send({req.query:req.query,req.params:req.params})return next()}
)
...curl -is -l http://localhost:8000/foo/male?nameabctitledef
HTTP/1.1 200 OK
Server: restify
Content-Type: application/json
Content-Length: 72
Date: Sun, 21 Jan 2024 13:11:52 GMT
Connection: keep-alive
Keep-Alive: timeout5{req.query:{name:abc,title:def},req.params:{sex:male,name:abc,title:def}}2.3. bodyParser
解析HTTP请求主体解析后生成req.body字段。
...
server.use(restify.plugins.queryParser({mapParams:true}),restify.plugins.bodyParser()
)
server.get(/foo/:sex,(req,res,next){res.send({req.query:req.query,req.params:req.params,req.body:JSON.parse(req.body)})return next()}
)
...curl -is -X GET -d {\a\:1,\b\:2,\c\:{\d\:3,\e\:\asdf\}} -l http://localhost:8000/foo/male
HTTP/1.1 200 OK
Server: restify
Content-Type: application/json
Content-Length: 92
Date: Sun, 21 Jan 2024 14:06:09 GMT
Connection: keep-alive
Keep-Alive: timeout5{req.query:{},req.params:{sex:male},req.body:{a:1,b:2,c:{d:3,e:asdf}}}2.4. serveStatic
提供静态文件。该插件需要映射到路由上
server.get(/static/*,restify.plugins.serveStatic({directory:__dirname,default:index.html
}))实际路径为主程序所在目录(__dirname)‘/static/’。
鉴权机制
Restify-auth是基于jwt的鉴权中间件。使用前需要先安装
npm i restify-auth -S1. 基本使用
const restifyrequire(restify)
const {restifyAuth} require(restify-auth)const serverrestify.createServer()
const authrestifyAuth({secret:test-secret //设定一个salt密码
})server.pre(restify.plugins.pre.sanitizePath())
server.use(restify.plugins.queryParser(),restify.plugins.bodyParser()
)
server.get(/getauth,auth.authorizer, //在需要鉴权的路由添加async (req,res){res.send(req.auth)}
)
server.post(/login,async (req,res){var userreq.body.user||var passwordreq.body.password||if(usertestpasswordtest){ //用户验证var tokenawait auth.sign({user})res.header(authorization,token)res.send({success:true})}else{res.send({success:false})}}
)server.on(restifyError,(req,res,err,cb){console.log(err.toString())return cb()
})server.listen(8000,(){console.log(server.name)console.log(server.url)
})客户端请求
curl -is -d usertestpasswordtest -l http://localhost:8000/login
HTTP/1.1 200 OK
Server: restify
authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdCIsImlhdCI6MTcwNTg0MDUzOCwiZXhwIjoxNzA1ODQxNzM4fQ.NK9F-FntUQHqXuEACQ94T2XKmTO3U8UxpZdaLegT8ko
Content-Type: application/json
Content-Length: 16
Date: Sun, 21 Jan 2024 12:35:38 GMT
Connection: keep-alive
Keep-Alive: timeout5{success:true}在应答报文头中authorization字段包含了从服务器返回的token使用该token可访问服务器需要鉴权的路由
curl -is -H authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoidGVzdCIsImlhdCI6MTcwNTg0MDUzOCwiZXhwIjoxNzA1ODQxNzM4fQ.NK9F-FntUQHqXuEACQ94T2XKmTO3U8UxpZdaLegT8ko -l http://localhost:8000/getauth
HTTP/1.1 200 OK
Server: restify
Content-Type: application/json
Content-Length: 49
Date: Sun, 21 Jan 2024 12:38:20 GMT
Connection: keep-alive
Keep-Alive: timeout5{user:test,iat:1705840538,exp:1705841738}若token错误或不提供token则无法访问该路由
curl -is -l http://localhost:8000/getauth
HTTP/1.1 401 Unauthorized
Server: restify
Content-Type: application/json
Content-Length: 53
Date: Sun, 21 Jan 2024 12:40:00 GMT
Connection: keep-alive
Keep-Alive: timeout5{code:Unauthorized,message:token is required}2. token过期和刷新
可设置token有效期和刷新周期
...
const authrestifyAuth({secret:test-secret,expiresIn:20m, //有效期20分钟refreshRange:0.6 //刷新时间为超过有效期60%时向客户端发送新token新token在报文头的authorization字段中客户端检测到新token后应及时更新token。
})
...