Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
538 views
in Technique[技术] by (71.8m points)

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

Here's my problem: I have an API in NestJS, it is hosted on Firebase (Cloud functions). My client is an Ionic - Angular web interface.

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

When I test the application locally with the command npm run start everything works fine.

When I test in production with firebase serve --only functions or firebase deploy --only functions, I get the following error (on browser) when launching the server :

console network tab console error message

Some of them are good, the other not.

here is a bad one:

bad http request

and a good one:

good http request

Once the first slave of requests is made, everything will run again for the next 5 minutes.

console network tab

You'll tell me that it's not serious, I just have to make the requests when I put the API in production and the users will be able to use it normally. Except that when the functions are not used for about 5 minutes, the API in production pauses, then it restarts as soon as it receives a request. This behavior seems normal to me, but because of errors and therefore inconsistencies in the results on the interface.

Here is my index.ts on my 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);

My question is this: How can I make sure that the cors are activated from the beginning when the server is launched and do not return an error at launch?

SOLUTION :

Thanks to NeatNerd, here is the solution : Tutorial to follow : https://softwarebrothers.co/blog/setting-up-nestjs-with-firebase-functions/

my new 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(
          '


The CORS policy for this site does not allow access from ',
          origin,
        );
        callback(
          new Error(
            '




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

I was missing the reference to createNestServer for each call. The tutorial that allowed me to set it up doesn't have this part. However, it is still quite complementary. https://fireship.io/snippets/setup-nestjs-on-cloud-functions/

The following option is also part of the solution : (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,
};

This allows to keep the connexion open.

question from:https://stackoverflow.com/questions/65644286/nestjs-prod-on-firebase-has-been-blocked-by-cors-policy-no-access-control-all

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to do two things:

  1. Setup NestJS with Firebase functions properly. Here is an example of how to do it.
  2. Check Firebase logs either in console or by running firebase functions:log. I am pretty sure there is something else going on

When you start the deployment, the old function is up and running until the deployment is finished, so there will no disruption of service.

Additionally, since the error actually pointing out to CORS, you want also to have a look at how to set up this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...