您好,登錄后才能下訂單哦!
近期使用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 也是剛剛使用,有好的使用案例可以在評論區分享,值得優化的地方可以留言給我。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。