response.middleware.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import { IMiddleware } from '@midwayjs/core';
  2. import { Middleware, App } from '@midwayjs/decorator';
  3. import { NextFunction, Context, Application } from '@midwayjs/koa';
  4. import { VOBase } from '../interface/VOBase';
  5. import { get } from 'lodash';
  6. import { ErrorVO } from '../interface/ErrorVO';
  7. import { ServiceError } from '../error/service.error';
  8. /**
  9. * 返回结果处理拦截器
  10. * 响应头的content-type含有'/files'的情况为请求文件,重写响应头即可
  11. * 正常请求都要通过视图处理基类(VOBase)格式化后返回
  12. */
  13. @Middleware()
  14. export class ResponseMiddleware implements IMiddleware<Context, NextFunction> {
  15. @App()
  16. app: Application;
  17. resolve() {
  18. return async (ctx: Context, next: NextFunction) => {
  19. await next();
  20. // 过滤掉 api文档的请求
  21. const swaggerPath = this.app.getConfig()?.swagger?.swaggerPath;
  22. const url = get(ctx, 'request.originalUrl');
  23. if (!url.includes(swaggerPath)) {
  24. //检查返回头,如果返回头中有/files,那就说明是读取文件.不能更改body
  25. const response = ctx.response;
  26. const resHeaderContentType = response.header['content-type'] as string;
  27. // 没有数据的情况,保证也可以返回
  28. if (!resHeaderContentType || !resHeaderContentType.includes('/files')) {
  29. const body = response.body;
  30. if (body instanceof ServiceError) {
  31. const r = new ErrorVO(body);
  32. return r;
  33. }
  34. const nb = new VOBase(body as object);
  35. return nb;
  36. } else {
  37. response.set('content-type', resHeaderContentType.replace('/files', ''));
  38. }
  39. }
  40. };
  41. }
  42. static getName(): string {
  43. return 'response';
  44. }
  45. }