Firebase 上的 NestJS prod:已被 CORS 政策阻止:没有“Access-Control-Allow-Origin”标头 - 仅在服务器启动时

问题描述

这是我的问题: 我在 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 进行生产测试时,我在启动服务器时收到以下错误(在浏览器上):

console network tab

console error message

有些很好,有些不好。

这里有一个不好的:

bad http request

而且还不错:

good http request

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

console network tab

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

这是我的 nestJS api 上的 index.ts:


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 在服务器启动时从一开始就被激活,并且在启动时不返回错误

解决方案:

感谢 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,];

  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 ',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,);
      }
    },});

  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