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