firebase 上的 NestJS prod:已被 CORS 策略阻止:否 'Access-Control-Allow-Origin' header - 仅当服务器启动时

NestJS prod on firebase: Has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header - only when server starts

这是我的问题: 我在 NestJS 中有一个 API,它托管在 Firebase(云函数)上。 我的客户端是 Ionic - Angular 网络界面。

"@nestjs/cli": "^7.5.1",
"@types/node": "^14.14.6",
"typescript": "^4.0.5"

当我使用命令 npm run start 在本地测试应用程序时,一切正常。

当我使用 firebase serve --only functionsfirebase deploy --only functions 在生产中进行测试时,启动服务器时出现以下错误(在浏览器上):

有的好,有的不好。

这里有一个不好的:

一个不错的:

一旦发出第一个请求的奴隶,接下来的 5 分钟内一切都会 运行。

你说不严重,我把API上线的时候再提要求,用户就可以正常使用了。 除了当功能没有使用大约 5 分钟时,生产中的 API 暂停,然后在收到请求后立即重新启动。这种行为对我来说似乎很正常,但由于错误,因此界面上的结果不一致。

这是我的 index.ts 我的 NestJS api:


const server = express();


export const createNestServer = async (expressInstance) => {
  const app = await NestFactory.create(
    AppModule,
    new ExpressAdapter(expressInstance),
  );

  const whitelist = [
    'http://localhost:8100/',
    'http://localhost:8100',
    '*',
    undefined,
  ];
  app.enableCors({
    origin: function (origin, callback) {
      if (whitelist.indexOf(origin) !== -1) {
        console.log('allowed cors for:', origin);
        callback(null, true);
      } else {
        console.log('blocked cors for:', origin);
        callback(new Error('Not allowed by CORS'));
      }
    },
    allowedHeaders:
      'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe',
    methods: 'GET, OPTIONS',
    credentials: true,
    preflightContinue: true,
    optionsSuccessStatus: 200,
  });

  return app.init();
}

createNestServer(server)
  .then((v) => console.log('Nest Ready'))
  .catch((err) => console.error('Nest broken', err));

export const api = functions.https.onRequest(server);

我的问题是:如何确保 cors 在服务器启动时从一开始就被激活并且不会 return 启动时出错?

解决方案:

感谢 NeatNerd,这是解决方案: 要遵循的教程:https://softwarebrothers.co/blog/setting-up-nestjs-with-firebase-functions/

我的新 index.ts :

import { NestFactory } from '@nestjs/core';
import { ExpressAdapter } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import * as express from 'express';
import * as functions from 'firebase-functions';
const server = express();

export const createNestServer = async (expressInstance) => {
  const app = await NestFactory.create(
    AppModule,
    new ExpressAdapter(expressInstance),
  );

  const whitelist = [
    'http://localhost:8100/',
    'http://localhost:8100',
    '*',
    undefined,
  ];

  app.enableCors({
    origin: function (origin, callback) {
      console.log(origin);
      if (whitelist.filter((x) => x && x.startsWith(origin))) {
        console.log('The CORS policy for this site allow access from ', origin);
        callback(null, true);
      } else {
        console.log(
          '\n\n\nThe CORS policy for this site does not allow access from ',
          origin,
        );
        callback(
          new Error(
            '\n\n\n\n\n The CORS policy for this site does not allow access from ' +
              origin,
          ),
          false,
        );
      }
    },
    allowedHeaders:
      'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept, Observe',
    methods: 'GET, OPTIONS',
    credentials: true,
    preflightContinue: true,
    optionsSuccessStatus: 200,
  });

  return app.init();
};

createNestServer(server)
  .then((v) => console.log('Nest Ready'))
  .catch((err) => console.error('Nest broken', err));

export const api = functions
  .region('us-central1')
  .https.onRequest(async (request, response) => {
    await createNestServer(server);
    server(request, response);
  });

我缺少对每次调用的 createNestServer 的引用。允许我设置它的教程没有这部分。但是,它仍然具有很强的互补性。 https://fireship.io/snippets/setup-nestjs-on-cloud-functions/

以下选项也是解决方案的一部分:(keepConnectionAlive)``

export const config: TypeOrmModuleOptions = {
  type: 'mysql',
  port: 3306,
  host: 'xxx.xxx.xxx.xxxx',
  database: 'name_of_the_database',
  username: 'username',
  password: 'password',
  synchronize: false,
  entities: [Entity1, Entity2],
  autoLoadEntities: true,
  keepConnectionAlive: true,
};

这允许保持连接打开。

你需要做两件事:

  1. 使用 Firebase 正常设置 NestJS。 example 如何操作。
  2. console 或 运行 firebase functions:log 中检查 Firebase 日志。我很确定还有其他事情正在发生

当您开始部署时,旧功能启动,运行直到部署完成,因此不会中断服务。

此外,由于错误实际上指向 CORS,您还想看看如何设置 this