Ionic 2: POST JSON Cross Origin CORS 403 Forbidden Hate Your Life

Trying to POST some JSON cross-origin and getting 403 forbidden? Hate your life? Me too.

The Problem:

Sometimes you need to post some data, most likely JSON, cross origin. That is from one domain to another. Technically, your Ionic 2 app is a website, it runs on its own local domain (at least that's how I understand it). If you want to POST some data from that app to an external domain, e.g. gurglingnuns.com, you will need to enable CORS at your server and construct your client http request in a specific way. Otherwise you will get 403 forbidden.

The Fix:

Contrary to how other http requests might work, your http request needs to have its headers wrapped with a RequestOptions object. This will cause the request to get the appropriate CORS options from the server before attempting the actual POST and then it will all magically work (providing you have CORS enabled at your server, see note below).

Example: Say I want to upload some super hot video details to my speciality website gurglingnuns.com, this is how I'd do it from SomeCrappyService class:

import { Injectable } from '@angular/core';
import {Http, Headers, RequestOptions} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';


@Injectable()
export class SomeCrappyService {

  constructor(public _http: Http) {}

  uploadSuperHotVideoDetails(videoDetails: any) {
    let hdrs = new Headers();
    hdrs.append('Content-Type', "application/json");      

    let options = new RequestOptions({ headers: hdrs});

    var url = "https://www.gurglingnuns.com";
    var params = {
      name: videoDetails.name,
      description: videoDetails.description
    };

    this._http.post(url, JSON.stringify(params), options).toPromise().then(
      response => {
        alert('Nuns are super hot.');
      }      
    ).catch((error: any) => {      
      // balls.
    });
  }  
 
}

See that the headers are wrapped in a RequestOptions object? Without that wrapper, this will fail.
I spent 2 days finding this out for you.

Note:

You must have CORS enabled on your webserver/backend. In my case it was an AWS API Gateway. To enable CORS in my AWS API Gateway, I had to first find it in the console, then click Actions:

Default Alt Text

This is a specific example illustrating how I set up my backend. Your server set up may be quite different.

Conclusion:

CORS is really annoying but probably useful. I hate my life and you do too.

Cheers.

Comments: