這次給大家?guī)?lái)Egg.js里如何獲取HTTP參數(shù),Egg.js里獲取HTTP參數(shù)的注意事項(xiàng)有哪些,下面就是實(shí)戰(zhàn)案例,一起來(lái)看一下。
在Egg.js框架中,由于 Controller基本上是業(yè)務(wù)開(kāi)發(fā)中唯一和HTTP 協(xié)議打交道的地方,所以框架通過(guò)在 Controller上綁定的 Context實(shí)例,提供了許多便捷方法和屬性獲取用戶通過(guò) HTTP請(qǐng)求發(fā)送過(guò)來(lái)的參數(shù)。本文就總結(jié)一下獲取http請(qǐng)求的參數(shù)方法:
1.query
在 URL 中 ?后面的部分是一個(gè) Query String,這一部分經(jīng)常用于 GET 類型的請(qǐng)求中傳遞參數(shù)。例如 GET /search?name=egg&age=26中 name=egg&age=26 就是用戶傳遞過(guò)來(lái)的參數(shù)。我們可以通過(guò) context.query(為一個(gè)對(duì)象)拿到解析過(guò)后的這個(gè)參數(shù)體
module.exports = app => { class SearchController extends app.Controller { * search() { const queryObj = this.ctx.query; console.log(queryObj.age); console.log(queryObj); //打印結(jié)果:{ name: 'egg', age: '26' } } } return SearchController; };
當(dāng) Query String 中的 key 重復(fù)時(shí),context.query只取 key 第一次出現(xiàn)時(shí)的值,后面再出現(xiàn)的都會(huì)被忽略。GET /posts?category=egg&category=koa 通過(guò) context.query拿到的值是 { category: 'egg' }。
1.1 queries
有時(shí)候我們的系統(tǒng)會(huì)設(shè)計(jì)成讓用戶傳遞相同的 key,例如 GET /posts?category=egg&id=1&id=2&id=3。針對(duì)此類情況,框架提供了 context.queries 對(duì)象,這個(gè)對(duì)象也解析了 Query String,但是它不會(huì)丟棄任何一個(gè)重復(fù)的數(shù)據(jù),而是將他們都放到一個(gè)數(shù)組中:
// GET /posts?category=egg&id=1&id=2&id=3const Controller = require('egg').Controller;module.exports = class PostController extends Controller { * listPosts() { console.log(this.ctx.queries); //result: // { // category: [ 'egg' ], // id: [ '1', '2', '3' ], // } } };
context.queries上所有的 key 如果有值,也一定會(huì)是數(shù)組類型。
2. Router params
我們知道在 Router 上也可以申明參數(shù),這些參數(shù)都可以通過(guò) context.params獲取到。
// app.get('/projects/:projectId/app/:appId', 'app.listApp');// GET /projects/1/app/2const Controller = require('egg').Controller;module.exports = class AppController extends Controller { * listApp() { assert.equal(this.ctx.params.projectId, '1'); assert.equal(this.ctx.params.appId, '2'); } };
3. body
雖然我們可以通過(guò) URL 傳遞參數(shù),但是還是有諸多限制:
瀏覽器中會(huì)對(duì) URL 的長(zhǎng)度有所限制,如果需要傳遞的參數(shù)過(guò)多就會(huì)無(wú)法傳遞。
服務(wù)端經(jīng)常會(huì)將訪問(wèn)的完整 URL 記錄到日志文件中,有一些敏感數(shù)據(jù)通過(guò) URL 傳遞會(huì)不安全。
我們知道在 header之后還有一個(gè) body部分,我們通常會(huì)在這個(gè)部分傳遞 POST、PUT 和 DELETE 等方法的參數(shù)。一般請(qǐng)求中有 body的時(shí)候,客戶端(瀏覽器)會(huì)同時(shí)發(fā)送 Content-Type告訴服務(wù)端這次請(qǐng)求的 body 是什么格式的。Web 開(kāi)發(fā)中數(shù)據(jù)傳遞最常用的兩類格式分別是 JSON和 Form。
框架內(nèi)置了 bodyParser 中間件來(lái)對(duì)這兩類格式的請(qǐng)求 body 解析成 object 掛載到 context.request.body上。HTTP協(xié)議中并不建議在通過(guò) GET、HEAD 方法訪問(wèn)時(shí)傳遞 body,所以我們無(wú)法在 GET、HEAD 方法中按照此方法獲取到內(nèi)容。
// POST /api/posts HTTP/1.1// Host: localhost:3000// Content-Type: application/json; charset=UTF-8//// {"title": "controller", "content": "what is controller"}const Controller = require('egg').Controller;module.exports = class PostController extends Controller { * listPosts() { assert.equal(this.ctx.request.body.title, 'controller'); assert.equal(this.ctx.request.body.content, 'what is controller'); } };
框架對(duì) bodyParser 設(shè)置了一些默認(rèn)參數(shù),配置好之后擁有以下特性:
當(dāng)請(qǐng)求的 Content-Type 為 application/json,application/json-patch+json,application/vnd.api+json 和 application/csp-report 時(shí),會(huì)按照 json格式對(duì)請(qǐng)求 body 進(jìn)行解析,并限制 body 最大長(zhǎng)度為 100kb。
當(dāng)請(qǐng)求的 Content-Type 為 application/x-www-form-urlencoded 時(shí),會(huì)按照 form 格式對(duì)請(qǐng)求 body 進(jìn)行解析,并限制 body 最大長(zhǎng)度為 100kb。
如果解析成功,body 一定會(huì)是一個(gè) Object(可能是一個(gè)數(shù)組)。
一般來(lái)說(shuō)我們最經(jīng)常調(diào)整的配置項(xiàng)就是變更解析時(shí)允許的最大長(zhǎng)度,可以在 config/config.default.js中覆蓋框架的默認(rèn)值
module.exports = { bodyParser: { jsonLimit: '1mb', formLimit: '1mb', }, };
如果用戶的請(qǐng)求 body 超過(guò)了我們配置的解析最大長(zhǎng)度,會(huì)拋出一個(gè)狀態(tài)碼為 413 的異常,如果用戶請(qǐng)求的 body 解析失敗(錯(cuò)誤的 JSON),會(huì)拋出一個(gè)狀態(tài)碼為 400的異常。
相信看了本文案例你已經(jīng)掌握了方法,更多精彩請(qǐng)關(guān)注Gxl網(wǎng)其它相關(guān)文章!
推薦閱讀:
mysqld_multi部署單機(jī)詳解
怎樣用一條SQL語(yǔ)句查詢不同的數(shù)據(jù)庫(kù)
JS獲取select下拉框中第一順位元素內(nèi)的值
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com