Nestjs 内置了一个 cros 跨域中间件,但只能针对 origin 动态配置,且功能有限,其余都是静态配置,可操作性不强,比如,需要针对 「Access-Control-Allow-Headers」 根据请求页面的 request-headers 动态追加时,就不能满足了。

第一步,引入 cros 中间件

// cros.ts
import { Request, Response, NextFunction } from 'express';

import { PREFLIGHT } from '../constants';

export function cros(request: Request, response: Response, next: NextFunction) {
  // @ts-ignore
  const { method, headers, logger, url } = request;
  const allowHeaders = headers['access-control-request-headers'] || headers['Access-Control-Request-Headers'] || '';

  const cropHeaders = {
    'Access-Control-Allow-Origin': headers.origin || '*',
    'Access-Control-Allow-Credentials': true,
    'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
    'Access-Control-Allow-Headers': `swimlane, ${allowHeaders}`,
    'Access-Control-Max-Age': 600,
    'Vary': 'Origin',
  }

  if (method.toLocaleLowerCase() === 'options') {
    // 记录日志,便于线上定位问题
    logger.info(PREFLIGHT, {
      url,
      result: JSON.stringify(headers)
    });
    response.statusCode = 204;
    response.setHeader('Content-Length', '0');
    for(var key in cropHeaders) {
      response.setHeader(key, cropHeaders[key]);
    }
    response.end();
  } else {
    for(var key in cropHeaders) {
      response.setHeader(key, cropHeaders[key]);
    }
    next();
  }
};

第二步,在 app 启动时,注册

app.use(cros);

https://docs.nestjs.com/security/cors

https://github.com/expressjs/cors/blob/master/lib/index.js