前言

狭义中间件的要素常见要素如下所示。

  • 一切皆中间件
  • 中间件内操作请求request
    • 请求拦截
  • 中间件内操作响应response
    • 响应拦截
  • 中间件内操作上下文context
    • 直接上下文代理,初始化实例时候挂载代理在app.context
    • 请求过程上下文代理,请求时候挂载代理在ctx
  • 大部分直接被app.use()加载

    • 注意: 初始化实例挂载代理context不被app.use()

      请求拦截

      1. const Koa = require('koa');
      2. let app = new Koa();
      3. const middleware = async function(ctx, next) {
      4. // 中间件 拦截请求
      5. // 把所有请求不是 /page/ 开头的路径全部抛出500错误
      6. const reqPath = ctx.request.path;
      7. if( reqPath.indexOf('/page/') !== 0 ) {
      8. ctx.throw(500)
      9. }
      10. await next();
      11. }
      12. const page = async function(ctx, next) {
      13. ctx.body = `
      14. <html>
      15. <head></head>
      16. <body>
      17. <h1>${ctx.request.path}</h1>
      18. </body>
      19. </html>
      20. `;
      21. }
      22. app.use(middleware);
      23. app.use(page);
      24. app.listen(3001, function(){
      25. console.log('the demo is start at port 3001');
      26. })

      响应拦截

      1. const Koa = require('koa');
      2. let app = new Koa();
      3. const middleware = async function(ctx, next) {
      4. ctx.response.type = 'text/plain';
      5. await next();
      6. }
      7. const page = async function(ctx, next) {
      8. ctx.body = `
      9. <html>
      10. <head></head>
      11. <body>
      12. <h1>${ctx.path}</h1>
      13. </body>
      14. </html>
      15. `;
      16. }
      17. app.use(middleware);
      18. app.use(page);
      19. app.listen(3001, function(){
      20. console.log('the demo is start at port 3001');
      21. })

      context挂载代理

  • 请求代理注入

    • 直接被app.use
    • 请求时候才有注入
    • 每次请求的注入都不同
  • 初始化实例(应用)代理注入
    • 直接注入到app.context
    • 初始化应用的时候才注入
    • 只注入一次,每次请求都可以使用

      请求时挂载代理context

      1. const Koa = require('koa');
      2. let app = new Koa();
      3. const middleware = async function(ctx, next) {
      4. // 中间件 代理/挂载上下文
      5. // 把所有当前服务的进程PID,内存使用情况方法代理/挂载在ctx上
      6. ctx.getServerInfo = function() {
      7. function parseMem( mem = 0 ) {
      8. let memVal = mem / 1024 / 1024;
      9. memVal = memVal.toFixed(2) + 'MB';
      10. return memVal;
      11. }
      12. function getMemInfo() {
      13. let memUsage = process.memoryUsage();
      14. let rss = parseMem(memUsage.rss);
      15. let heapTotal = parseMem(memUsage.heapTotal);
      16. let heapUsed = parseMem(memUsage.heapUsed);
      17. return {
      18. pid: process.pid,
      19. rss,
      20. heapTotal,
      21. heapUsed
      22. }
      23. }
      24. return getMemInfo()
      25. };
      26. await next();
      27. }
      28. const page = async function(ctx, next) {
      29. const serverInfo = ctx.getServerInfo();
      30. ctx.body = `
      31. <html>
      32. <head></head>
      33. <body>
      34. <p>${JSON.stringify(serverInfo)}</p>
      35. </body>
      36. </html>
      37. `;
      38. }
      39. app.use(middleware);
      40. app.use(page);
      41. app.listen(3001, function(){
      42. console.log('the demo is start at port 3001');
      43. })

      初始化实例挂载代理context

      1. const Koa = require('koa');
      2. let app = new Koa();
      3. const middleware = function(app) {
      4. // 中间件在初始化实例 把getServerInfo方法 挂载代理到上下文
      5. app.context.getServerInfo = function() {
      6. function parseMem( mem = 0 ) {
      7. let memVal = mem / 1024 / 1024;
      8. memVal = memVal.toFixed(2) + 'MB';
      9. return memVal;
      10. }
      11. function getMemInfo() {
      12. let memUsage = process.memoryUsage();
      13. let rss = parseMem(memUsage.rss);
      14. let heapTotal = parseMem(memUsage.heapTotal);
      15. let heapUsed = parseMem(memUsage.heapUsed);
      16. return {
      17. pid: process.pid,
      18. rss,
      19. heapTotal,
      20. heapUsed
      21. }
      22. }
      23. return getMemInfo()
      24. };
      25. }
      26. middleware(app);
      27. const page = async function(ctx, next) {
      28. const serverInfo = ctx.getServerInfo();
      29. ctx.body = `
      30. <html>
      31. <head></head>
      32. <body>
      33. <p>${JSON.stringify(serverInfo)}</p>
      34. </body>
      35. </html>
      36. `;
      37. }
      38. app.use(page);
      39. app.listen(3001, function(){
      40. console.log('the demo is start at port 3001');
      41. })