NestJS prod на firebase: заблокирован политикой CORS: нет заголовка ‘Access-Control-Allow-Origin’ — только при запуске сервера

#javascript #firebase #google-cloud-functions #nestjs #http-status-code-504

#javascript #firebase #google-cloud-функции #nestjs #http-status-code-504

Вопрос:

Вот моя проблема: у меня есть API в NestJS, он размещен на Firebase (облачные функции). Мой клиент — это веб-интерфейс с ионно-угловым интерфейсом.

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

Когда я тестирую приложение локально с помощью команды npm run start , все работает нормально.

Когда я тестирую в рабочей среде с firebase serve --only functions помощью или firebase deploy --only functions , я получаю следующую ошибку (в браузере) при запуске сервера :

вкладка консольная сеть
сообщение об ошибке консоли

Некоторые из них хороши, другие нет.

вот один плохой:

плохой http-запрос

и очень хороший:

хороший http-запрос

Как только будет выполнен первый подчиненный запрос, все будет выполняться снова в течение следующих 5 минут.

вкладка консольная сеть

Вы скажете мне, что это несерьезно, мне просто нужно делать запросы, когда я запускаю API в производство, и пользователи смогут использовать его в обычном режиме. За исключением того, что, когда функции не используются около 5 минут, API в рабочей среде приостанавливается, а затем перезапускается, как только получает запрос. Такое поведение кажется мне нормальным, но из-за ошибок и, следовательно, несоответствий в результатах в интерфейсе.

Вот мой index.ts в моем API NestJS:

 
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,
    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 amp;amp; x.startsWith(origin))) {
        console.log('The CORS policy for this site allow access from ', origin);
        callback(null, true);
      } else {
        console.log(
          'nnnThe CORS policy for this site does not allow access from ',
          origin,
        );
        callback(
          new Error(
            'nnnnn 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:

Вам нужно сделать две вещи:

  1. Правильно настройте NestJS с Firebase. Вот пример того, как это сделать.
  2. Проверьте журналы Firebase либо в консоли , либо с помощью запуска firebase functions:log . Я почти уверен, что происходит что-то еще

Когда вы начинаете развертывание, старая функция запущена и работает до завершения развертывания, поэтому сбоев в обслуживании не будет.

Кроме того, поскольку ошибка на самом деле указывает на CORS, вы также хотите взглянуть на то, как это настроить.

Комментарии:

1. Большое вам спасибо! Действительно, этот учебник более полный, чем тот, которому я следовал ( fireship.io/snippets/setup-nestjs-on-cloud-functions ) и конец будет другим. Я опубликую более подробную информацию, чтобы объяснить исправление.