您好,登錄后才能下訂單哦!
近期使用node做服務(wù)端渲染,作為中間層需要請(qǐng)求后端接口,需要封裝服務(wù)端的請(qǐng)求,接下來(lái)來(lái)了解下如何使用 request。
基本使用
const request = require('request')
引入這個(gè)包就可以開(kāi)始使用了,最簡(jiǎn)單的使用方式就是 request(url) 就可以想指定的地址發(fā)起一個(gè) get 請(qǐng)求。 從這里我們可以看出 request 暴露出來(lái)的就是一個(gè)函數(shù)。其實(shí)它內(nèi)部的結(jié)構(gòu)如下
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) }
可以看出它默認(rèn)接收三個(gè)函數(shù),并且第一個(gè)參數(shù)值必須存在,request的傳參方式也有很多種,本身做了很多支持的處理,來(lái)看看它支持的傳參數(shù)方式。
入?yún)⒏袷?/strong>
url 必填,可以單獨(dú)放在第一個(gè)參數(shù),或者作為 option 的屬性之一。其他都是可選。
// 方式一 request(url,options,callback) // 方式二 let options = { url // 必填 } request(options,callback)
簡(jiǎn)寫(xiě)方式
// 方式一 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 支持這么多種傳參數(shù)方式。來(lái)看看它內(nèi)部的實(shí)現(xiàn)方式
源碼
下面代碼可以看出,request 對(duì)參數(shù)類(lèi)型進(jìn)行類(lèi)型判斷來(lái)采用不同的合并方式,最終 return 的params要求就是要包含url請(qǐng)求地址。
function initParams (uri, options, callback) { // 處理沒(méi)有傳 options 的情況 if (typeof options === 'function') { callback = options } var params = {} if (typeof options === 'object') { extend(params, options, {uri: uri}) // 傳遞的 url 最終也會(huì)被合并到 pramas 上 // 并且如果你在 options 傳遞了 uri 會(huì)被第一參數(shù)覆蓋,優(yōu)先級(jí)以 第一個(gè)入?yún)ri為準(zhǔn) } else if (typeof uri === 'string') { extend(params, {uri: uri}) } else { // 處理第一參數(shù)不是url的情況 extend(params, uri) } params.callback = callback || params.callback return params }
常用字段
request(options,callback) 提供 baseUrl 來(lái)統(tǒng)一設(shè)置域名部分及公共部分。
// 定義了 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) } }) }) } // 使用,只傳遞了接口部分最終會(huì)拼接成 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 不同數(shù)據(jù)類(lèi)型的請(qǐng)求及 debug
為了模擬node服務(wù)端請(qǐng)求后端的場(chǎng)景,啟動(dòng)兩個(gè)node服務(wù) ,一個(gè)作為請(qǐng)求方模擬(中間層),另一個(gè)作為后端。另外通過(guò) postman 來(lái)發(fā)起客戶(hù)端的請(qǐng)求。關(guān)于數(shù)據(jù)的驗(yàn)證可以使用 vscode 的 debug 功能 也可以開(kāi)啟 pm2 log 來(lái)驗(yàn)證請(qǐng)求的參數(shù)。
接下來(lái)看下 post 不同格式的請(qǐng)求方式的設(shè)置,不同與 axios , fetch 。request對(duì)于不同請(qǐng)求方式的數(shù)據(jù)接收的字段是不同的??梢酝ㄟ^(guò) body、form、formData 來(lái)接收。get的請(qǐng)求都是通過(guò) application/x-www-form-urlencoded 格式來(lái)傳遞數(shù)據(jù)的,所以這里暫不舉例。
application/x-www-form-urlencoded
通過(guò) forms字段
來(lái)接收入?yún)?,方法如下,直接將傳入的參?shù)對(duì)象傳遞給 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 有個(gè)debug 模式,通過(guò) request.debug = true
開(kāi)啟,為了查看debug信息,使用 pm2 start app.js --watch
啟動(dòng)項(xiàng)目,然后 pm2 log
來(lái)查看debug信息。紅色代表中間層的log,綠色代表后端的log
使用 node debug 查看接收到的 request.body是后端接收到的值 request.header是接收到的請(qǐng)求 content-type
都會(huì)將入?yún)鬟f到 body 這個(gè)字段上
form-data 文件上傳
通過(guò) formData
來(lái)傳遞文件,代碼如下:使用 fs.createReadStream 去拿到中間層的文件,然后通過(guò) formData 方式發(fā)送給后端。
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 , 我們并沒(méi)有手動(dòng)的去設(shè)置請(qǐng)求的 content-type 會(huì)自動(dòng)添加上。
下面代碼會(huì)將接收到到文件流寫(xiě)入到后端local??梢钥吹?icon-arrow.jpg 已經(jīng)成功的從中間層發(fā)送到后端
application/json
將參數(shù)通過(guò) body 傳遞,并且設(shè)置 json為ture,那么請(qǐng)求時(shí)會(huì)自動(dòng)將 content-type 設(shè)置為 application/json 并且將傳遞給 body 的對(duì)象轉(zhuǎn)義為 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' } })
通過(guò)id號(hào)來(lái)區(qū)分當(dāng)前進(jìn)程,
可以通過(guò) pm2 start app.js --name 請(qǐng)求端 來(lái)定義進(jìn)程名稱(chēng)
最后
關(guān)于 reqeust 也是剛剛使用,有好的使用案例可以在評(píng)論區(qū)分享,值得優(yōu)化的地方可以留言給我。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。