本文共 3145 字,大约阅读时间需要 10 分钟。
框架通过在 Controller 上绑定的 Context 实例,提供了许多便捷方法和属性获取用户通过 HTTP 请求发送过来的参数。
获取 url 的 ?后面的数据,通过 ctx.query
拿到数据:
// GET /posts?category=egg&language=nodeclass PostController extends Controller { async listPosts() { const query = this.ctx.query; // { // category: 'egg', // language: 'node', // } }}
获取 Router 上也可以申明参数,通过 ctx.params
拿到数据:
// app.get('/projects/:projectId/app/:appId', 'app.listApp');// GET /projects/1/app/2class AppController extends Controller { async listApp() { // assert.equal 相当于 == assert.equal(this.ctx.params.projectId, '1'); assert.equal(this.ctx.params.appId, '2'); // 或用解构赋值 const { projectId, appId } = this.ctx.params }}
也就是 post、put、delete 等方法,框架内置了 bodyParser 中间件来对这两类格式的请求 body 解析成 object 挂载到 ctx.request.body
上。
// POST /api/posts HTTP/1.1// Host: localhost:3000// Content-Type: application/json; charset=UTF-8//// {"title": "controller", "content": "what is controller"}class PostController extends Controller { async listPosts() { assert.equal(this.ctx.request.body.title, 'controller'); assert.equal(this.ctx.request.body.content, 'what is controller'); }}
可以在 config/config.default.js
配置解析请求的大小,会覆盖框架默认值 100kb:
module.exports = { bodyParser: { jsonLimit: '1mb', formLimit: '1mb', },};
注意区分:ctx.request.body 和 ctx.body :
ctx.body 是 ctx.response.body 的简写。
1、在 config 文件中启用 file 模式:
// config/config.default.jsexports.multipart = { mode: 'file',};
2、上传 / 接收文件:
前端:后端:
// app/controller/upload.jsconst Controller = require('egg').Controller;const fs = require('mz/fs');module.exports = class extends Controller { async upload() { const { ctx } = this; const file = ctx.request.files[0]; const name = 'egg-multipart-test/' + path.basename(file.filename); let result; try { // 处理文件,比如上传到云端 result = await ctx.oss.put(name, file.filepath); } finally { // 需要删除临时文件 await fs.unlink(file.filepath); } ctx.body = { url: result.url, // 获取所有的字段值 requestBody: ctx.request.body, }; }};
上传多个文件可以看 egg 官网
const path = require('path');const sendToWormhole = require('stream-wormhole');const Controller = require('egg').Controller;class UploaderController extends Controller { async upload() { const ctx = this.ctx; const stream = await ctx.getFileStream(); const name = 'egg-multipart-test/' + path.basename(stream.filename); // 文件处理,上传到云存储等等 let result; try { result = await ctx.oss.put(name, stream); } catch (err) { // 必须将上传的文件流消费掉,要不然浏览器响应会卡死 await sendToWormhole(stream); throw err; } ctx.body = { url: result.url, // 所有表单字段都能通过 `stream.fields` 获取到 fields: stream.fields, }; }}module.exports = UploaderController;
通过 ctx.getFileStream
获取文件的前提:
stream 模式上传多个文件使用 ctx.multipart()
ctx.headers
,ctx.header
,ctx.request.headers
,ctx.request.header
等价ctx.get(name)
,ctx.request.get(name)
获取 header 某一个字段转载地址:http://nopo.baihongyu.com/