近期使用node做服务端渲染,作为中间层需要请求后端接口,需要封装服务端的请求,接下来来了解下如何使用 request。
基本使用
const request = require('request')
引入这个包就可以开始使用了,最简单的使用方式就是 request(url) 就可以想指定的地址发起一个 get 请求。 从这里我们可以看出 request 暴露出来的就是一个函数。其实它内部的结构如下
function request (uri, options, callback) { if (typeof uri === 'undefined') { throw new Error('undefined is not a valid uri or options object.') } var params = initParams(uri, options, callback) if (params.method === 'HEAD' && paramsHaveRequestBody(params)) { throw new Error('HTTP HEAD requests MUST NOT include a request body.') } return new request.Request(params) }
可以看出它默认接收三个函数,并且第一个参数值必须存在,request的传参方式也有很多种,本身做了很多支持的处理,来看看它支持的传参数方式。
入参格式
url 必填,可以单独放在第一个参数,或者作为 option 的属性之一。其他都是可选。
// 方式一 request(url,options,callback) // 方式二 let options = { url // 必填 } request(options,callback)
简写方式
// 方式一 request.get(url,options,callback) // 方式二 let options = { url // 必填 } request.get(options,callback) // 方式一 request.post(url,options,callback) // 方式二 let options = { url } request.post(options,callback)
为啥 request 支持这么多种传参数方式。来看看它内部的实现方式
源码
下面代码可以看出,request 对参数类型进行类型判断来采用不同的合并方式,最终 return 的params要求就是要包含url请求地址。
function initParams (uri, options, callback) { // 处理没有传 options 的情况 if (typeof options === 'function') { callback = options } var params = {} if (typeof options === 'object') { extend(params, options, {uri: uri}) // 传递的 url 最终也会被合并到 pramas 上 // 并且如果你在 options 传递了 uri 会被第一参数覆盖,优先级以 第一个入参uri为准 } else if (typeof uri === 'string') { extend(params, {uri: uri}) } else { // 处理第一参数不是url的情况 extend(params, uri) } params.callback = callback || params.callback return params }
常用字段
request(options,callback) 提供 baseUrl 来统一设置域名部分及公共部分。
// 定义了 baseUrl 后只需要传递接口 api 即可 function fetchPost(path,params){ return new Promise( (resolve,reject)=>{ request.post(path,{ baseUrl:"http://localhost:9000/react/", },function(err, httpResponse, body){ if(err){ reject(err) }else{ resolve(body) } }) }) } // 使用,只传递了接口部分最终会拼接成 http://localhost:9000/react/c-request router.get('/c-request',async ctx=>{ let res = await fetchPost('request-header',{value:1,name:'dd'}) ctx.body = res })
reqeust 不同数据类型的请求及 debug
为了模拟node服务端请求后端的场景,启动两个node服务 ,一个作为请求方模拟(中间层),另一个作为后端。另外通过 postman 来发起客户端的请求。关于数据的验证可以使用 vscode 的 debug 功能 也可以开启 pm2 log 来验证请求的参数。
接下来看下 post 不同格式的请求方式的设置,不同与 axios , fetch 。request对于不同请求方式的数据接收的字段是不同的。可以通过 body、form、formData 来接收。get的请求都是通过 application/x-www-form-urlencoded 格式来传递数据的,所以这里暂不举例。
application/x-www-form-urlencoded
通过 forms字段
来接收入参,方法如下,直接将传入的参数对象传递给 form 即可。
function fetchPost(path,params){ return new Promise( (resolve,reject)=>{ request.debug = true request.post(path,{ form:params },function(err, httpResponse, body){ if(err){ reject(err) }else{ resolve(body) } }) }) }
request 有个debug 模式,通过 request.debug = true
开启,为了查看debug信息,使用 pm2 start app.js --watch
启动项目,然后 pm2 log
来查看debug信息。红色代表中间层的log,绿色代表后端的log
使用 node debug 查看接收到的 request.body是后端接收到的值 request.header是接收到的请求 content-type
都会将入参传递到 body 这个字段上
form-data 文件上传
通过 formData
来传递文件,代码如下:使用 fs.createReadStream 去拿到中间层的文件,然后通过 formData 方式发送给后端。
function fetchPost(path,params){ return new Promise( (resolve,reject)=>{ let formData = { file:fs.createReadStream(__dirname+'/../static/images/icon-arrow.png') } request.debug = true request.post(path,{ formData },function(err, httpResponse, body){ if(err){ reject(err) }else{ resolve(body) } }) }) }
可以看到后端接收到到 content-type 为 multipart/form-data , 我们并没有手动的去设置请求的 content-type 会自动添加上。
下面代码会将接收到到文件流写入到后端local。可以看到 icon-arrow.jpg 已经成功的从中间层发送到后端
application/json
将参数通过 body 传递,并且设置 json为ture,那么请求时会自动将 content-type 设置为 application/json 并且将传递给 body 的对象转义为 JSON
function fetchPost(path,params){ return new Promise( (resolve,reject)=>{ request.debug = true console.log('*'.repeat(40)); request.post(path,{ baseUrl:"http://localhost:9000/react/", body:params, json:true },function(err, httpResponse, body){ if(err){ reject(err) }else{ resolve(body) } }) }) }
header
request.post(path,{ form:params, headers:{ // 'content-type':'application/json', // ... 任意其他字段 name:'dd', agent:'request' } })
通过id号来区分当前进程,
可以通过 pm2 start app.js --name 请求端 来定义进程名称
最后
关于 reqeust 也是刚刚使用,有好的使用案例可以在评论区分享,值得优化的地方可以留言给我。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]