How to handle CORS in an Angular2 and Node/Express Applications

In many applications, the front-end and the backend reside at a single point i.e. there might be many NodeJS applications which serve the front-end using ExpressJS with JADE/Handlebars or other frameworks. But sometimes you might want to host your front-end somewhere else to isolate your backend. Or you might want to allow multiple domains to access your NodeJS backend. In such cases you have to enable CORS.

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the resource originated.[1]

Long story short, CORS allows other domains to access your backend resources you want to expose and also the API/REST calls.

For Angular2 applications, there are multiple starter templates available to choose from. Then there’s angular-cli for angular2 apps which is being used by many but it still currently is in its beta. They allow you to have your standalone server for angular apps. So when you’re building your Angular2 and NodeJS apps, your front-end and backend will be on different domains, and while development, probably on different ports. For example http://localhost:4200 could be your Angular2 app’s address and http://localhost:3000 might be your NodeJS api server.

By now you might be thinking “Oh come on Ahsan, I know all that.. Silly ! Just tell me how to do the CORS stuff ”. Lol ! Here we go.

On the NodeJS end, it is pretty simple. There’s this awesome npm package cors for ExpressJS that serves as a middleware. So install the package in your project using npm :

cd /path-to-your-project
npm install cors --save

Then in your main nodejs file, usually “app.js”, require the module and use the following configuration :

var express = require('express')
  ,cors = require('cors')
  , app = express();
//app.user(bodyParser.json());
// after the code that uses bodyParser and other cool stuff
var originsWhitelist = [
  'http://localhost:4200',      //this is my front-end url for development   'http://www.myproductionurl.com'
];
var corsOptions = {
  origin: function(origin, callback){
        var isWhitelisted = originsWhitelist.indexOf(origin) !== -1;
        callback(null, isWhitelisted);
  },
  credentials:true
}//here is the magic
app.use(cors(corsOptions));

The above code will enable CORS on your NodeJS+ExpressJS application. Now you need to prepare your Angular app to work for CORS. As of now there isn’t an official way to do this. There is a pull request on the Angular 2 github repository but I don’t think it has been merged yet. So here’s the deal. To enable CORS, you can extend the BrowserXhr class (considering you’re working on Typescript for Angular2) and include that in the bootstrapping process. Create a file in your Angular2 project named “cust-ext-browser-xhr.ts” and paste the following code:

import {Injectable} from "@angular/core";
import {BrowserXhr} from "@angular/http";@Injectable()
/**
 * @author AhsanAyaz
 * We're extending the BrowserXhr to support CORS
 */
export class CustExtBrowserXhr extends BrowserXhr {
  constructor() {
      super();
  }
  build(): any {
    let xhr = super.build();
    xhr.withCredentials = true;             // this is all the magic we need for now
    return <any>(xhr);
  }
}

Now in your main file where you bootstrap your app component, import our custom browser xhr module and use it in the bootstrap process :

Note: the below code is for Angular2, for Angular4+, scroll down further:

import { bootstrap } from ‘@angular/platform-browser-dynamic’;
import { provide } from ‘@angular/core’;
import { AppComponent} from ‘./app/’;
import { BrowserXhr } from ‘@angular/http’;
import {CustExtBrowserXhr} from ‘./app/path-to-file/cust-ext-browser-xhr’;bootstrap(AppComponent, [
 HTTP_PROVIDERS,
 provide(BrowserXhr,{useClass:CustExtBrowserXhr})
]);

For Angular4+, use the following snippet:

import { provide } from ‘@angular/core’;
import { AppComponent} from ‘./app/’;
import { BrowserXhr } from ‘@angular/http’;
import {CustExtBrowserXhr} from ‘./app/path-to-file/cust-ext-browser-xhr’;@NgModule({
  imports: [
    HttpModule,
    BrowserModule,
    …
  ],
  declarations: [AppComponent],
  providers: [
    {provide: BrowserXhr, useClass:CustExtBrowserXhr},
    {provide: LocationStrategy, useClass: HashLocationStrategy}
    …
  ],
  bootstrap: [ AppComponent ]
})

That’s it! That’s all we need to make CORS working in our Angular2 & NodeJS/ExpressJS applications. I use passport.js for authentication in my NodeJS applications which is an extremely flexible and easy to use framework.

Happy coding ! :)

212

212 claps
Muhammad Ahsan Ayaz

Written by

Software Architect @ModusCreate. Angular GDE | Loves Angular | Node | Ionic | JavaScript | Writes Blogs | Presents Speaker/Dev Sessions & Tech Talks