CORS is somehow stopping my Angular and Nestjs apps from communicating
Asked Answered
K

2

6

I'm building an app with Angular and NestJS using NGXS for state management. I got everything set up and served my application and got this error in the console.

Access to XMLHttpRequest at 'localhost:333/api/product-index' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

After doing a little research I found this article explaining how to handle CORS in our Angular apps and after checking the files it tells us to modify I saw that the settings were already present. I was confused about the server.js file it told us to update and after looking into what's typically done in a server.js file I came to the conclusion that in Angular it must be the main.ts file however I don't know if I need to make the modifications to the main.ts file in my Nest app or the one in my Angular app. I'm using a nrwl nx monorepo for my apps as well.

This is the proxy.conf.json file from my angular app

{
    "/cre8or-maker-backend": {
      "target": "http://localhost:3333",
      "secure": false,
      "logLevel": "debug"
    }
  }

This is the serve object of the architect object in my angular.json file.

"serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "cre8or-maker:build",
            "proxyConfig": "apps/cre8or-maker/proxy.conf.json"
          }

As I said before these settings were already present in these files and the only thing that seems new to me is the part about modifying the server.js file which I'm assuming is the main.ts file in Angular world. Here's what my main.ts files look like

nest main.ts

import { NestFactory } from '@nestjs/core';

import { AppModule } from './app/app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const globalPrefix = 'api';
  app.setGlobalPrefix(globalPrefix);
  const port = process.env.port || 3333;
  await app.listen(port, () => {
    console.log('Listening at http://localhost:' + port + '/' + globalPrefix);
  });
}

bootstrap();

angular main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

I installed the cors npm package already, I just don't know what else I'm suppose to do to get this working, can anyone help?

UPDATE I tried adding app.enableCors(); to the main.ts file in my NestJs app as well as modifying the create(AppModule) function to be create(AppModule, {cors: true}) and neither solve the problem. I also added the following snippet of code which didn't help either.

app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Accept');
    next();
  });

As of right now I only have one state defined making an API request to the back end. Inside my state I have an action which looks like this

@Action(GetProductIndexList)
    getProductIndexListData({patchState, dispatch, getState}: StateContext<ProductIndexListModel>){

       return this.dataService.fetchProductIndexList().pipe(tap((result)=>{
            const state = getState();

            patchState({items:[...state.items, ...result]});
        }));
    }

I make the api call inside of a service file which I'm calling dataService in the state's constructor. The service file looks like this.

@Injectable({ providedIn: 'root' })

export class ProductIndexService{

    constructor(private httpClient: HttpClient){}

    private readonly URL: string = 'localhost:3333/api';

    public fetchProductIndexList():Observable<CattegoryIndexItem[]>{
        const path: string = this.URL + '/product-index';

        return this.httpClient.get(path) as Observable<CattegoryIndexItem[]>;
    }
}

In NestJS I can successfully call the data without any errors so I know the controllers are set up properly but if anybody wants to see how I have things set up there let me know and I'll update this question with the code.

Kraken answered 30/3, 2020 at 5:30 Comment(9)
Does this answer your question? NestJS enable cors in productionDiaphysis
unfortunately that didn't help. I tried a couple things from it which I modified my question to show.Kraken
Can you show us where you send your request within the angular app?Diaphysis
I just updated the question again.Kraken
Try the following change to your URL: private readonly URL: string = 'https://localhost:3333/api';Diaphysis
in your nest main.ts , add the following lines ` app.enableCors({origin: ['*'],credentials: true or false});`Chintzy
ok I made the suggested modifications and the error went away, however I'm getting these errors now core.js:6185 ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "https://localhost:3333/api/product-index", ok: false, …} and GET https://localhost:3333/api/product-index net::ERR_CONNECTION_REFUSEDKraken
I followed steps mentioned in your question: app.enableCORS(); and app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type, Accept'); next(); }); and it worked for me to connect my angular app with nestjs api successfully. ThanksWichern
i add http:// before the localhost:3000 and only with nestjs app.enableCors(); it works! i was not need to proxy.conf.json - in the angular ( angular version 13 , nest version 8 )Incubation
K
2

I realized from the error I was making a request to localhost:333 rather than localhost:3333 in the service file sending requests to the backend. That made the CORS error go away but I still have the other errors which I started a new question to address.

Kraken answered 1/4, 2020 at 5:7 Comment(0)
A
6

For the following, I just ran into this issue while working on an Angular 13 and Nest.js 8 app in an NX workspace.

For my part, I finally solved this CORS problem by adding the line app.enableCors(); in the main.ts file of the Nest.js application.

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    const globalPrefix = 'api';
    app.setGlobalPrefix(globalPrefix);
    app.enableCors();
    const port = process.env.PORT || 3000;
    await app.listen(port);
    Logger.log(
        `🚀 Application is running on: http://localhost:${port}/${globalPrefix}`
    );
}

See the documentation:https://docs.nestjs.com/security/cors

Antipathetic answered 4/5, 2022 at 23:5 Comment(0)
K
2

I realized from the error I was making a request to localhost:333 rather than localhost:3333 in the service file sending requests to the backend. That made the CORS error go away but I still have the other errors which I started a new question to address.

Kraken answered 1/4, 2020 at 5:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.