0

I've my backend on some remote server for which I've the url. I need to render the data from there into my Ionic2,Angular2 project using HTTP GET and POST methods.But I'm thrown with this error when I'm trying to make a service call:

XMLHttpRequest cannot load http://192.162.91.159:8080/movieengine2/api/search/getMoviedetails. Response to preflight request doesn't pass access control check:No 'Access Control-Allow-Origin' header is present on the Requested resource.Origin 'http://localhost:8100' is therefore not allowed access/

I've searched quite a lot on the internet but most of those forums are too old. I've referred the following:

Angular 2 - No 'Access-Control-Allow-Origin' header is present on the requested resource

https://forum.ionicframework.com/t/cors-problem-with-ionic-2-and-angular-2-no-access-control-allow-origin-header-is-present-on-the-requested-resource/58350/6

https://forum.ionicframework.com/t/ionic-2-cors-issue/59815

https://github.com/angular/angular/issues/13554

This is what I've in my service file

import { Injectable } from '@angular/core';
import { Http, Headers, Response, RequestOptions, BaseRequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';

@Injectable()
export class TestService {
  backendUrl:string='';
  parameters: RequestOptions;

  constructor(public http: Http) {
    console.log('Hello TestService Provider');
  }

  private extractData(res: Response) {
    let body = res.json();
    return body || {};
  }

  private handleError(error: Response){
    return Observable.throw(error.json().error || 'Server Error')
  }


  get(url, params) 
  {
     var headers = new Headers
      ({
     'X-Requested-With': 'XMLHttpRequest'
      });
      headers.append("Accept", 'application/json');
     headers.append('Content-Type', 'application/json' );
      let options = new RequestOptions({ headers: headers });

        this.backendUrl='http://192.162.91.159:8080/movieengine2/api/search/'+url;
        return this.http.get(this.backendUrl).map(this.extractData).catch(this.handleError);
  }

I even tried adding this in my ionic.config.json

"proxies": [
{
    "path": "/api",
    "proxyUrl": "http://api.steampowered.com"
}

]

Can someone tell me how to avoid that issue ? I want a permanent solution which can work on either the device or the browser.Thanks in advance.These are the versions I'm using.

"cors": "^2.8.3",
"ionic-angular": "2.1.0",
"ionic-native": "2.4.1",
"ionicons": "3.0.0",
"rxjs": "5.0.0-beta.12",
"sw-toolbox": "3.4.0",
"underscore": "^1.8.3",
"zone.js": "0.6.26"

I'm unable to find a suitable solution for the version I'm using.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Impromptu_Coder
  • 425
  • 3
  • 7
  • 27
  • Your "proxies" makes no sense. You should declare a proxy for a path (like `/server`) and set the external destination URI. Then, in your code, replace `this.backendUrl` value with `/server`, this will solve your issue. Be aware that in production you must disable the proxies. Moreover, be aware that on iOS you CAN'T perform http requests to insecure servers anymore, so your backend must have an SSL protocol enable (hence must use HTTPs protocol). – briosheje Apr 14 '17 at 10:24
  • 1
    try to install cross extention in your chrome https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en – Mohan Gopi Apr 14 '17 at 10:28
  • @briosheje Could you please tell me how should I declare a proxy for my server.And also I didn't get what do you my proxies must be disabled in production.You mean to say they won't work when the app is released ? – Impromptu_Coder Apr 14 '17 at 10:42
  • the error is not in the proxy itself, it's in the code. The proxy ionic config works so that if the url matched is exactly "/api" it will replace "/api" with the proxyUrl declared. Currently, your code is NOT using it and you're not using it in the way it is supposed to be used. If your external server URI is "http://192.162.91.159:8080/movieengine2/api/search/", you need to set `/api` to "http://192.162.91.159:8080/movieengine2/api/search/" (in your proxy config) and, in your code, use: `this.backendUrl = "/api" + url;` – briosheje Apr 14 '17 at 10:46
  • @MohanGopi will that work while testing my app on a device also ? – Impromptu_Coder Apr 14 '17 at 10:49
  • @briosheje So you mean to say that I need to write it this way ? "proxies": [ { "path": "/api", "proxyUrl": "192.162.91.159:8080/movieengine2/api/search/" } Could you please provide me the code for whatever you've told. I'm getting confused. – Impromptu_Coder Apr 14 '17 at 10:52
  • @Impromptu_Coder : exactly, then, in your javascript (typescript in this case really), you set `this.backendUrl = "/api" + url;`. This is the correct way to do this, because your proxy knows that it needs to build the URI on top of "/api", which will be replaced by the proxyUrl, and knows that it needs to take care of the CORS. Remember to add `http://` to the proxyUrl aswell, it seems you have not copied it in your comment. – briosheje Apr 14 '17 at 10:58
  • @briosheje This is my proxy right now: "proxies": [{ "path": "/api", "proxyUrl": "http://192.162.91.159:8080/movieengine2/api/" }] and I've changed my backendUrl to "/api"+url; But I get this error now "GET http://localhost:8100/api/getFeaturedMovies 404 (Not Found).It says "SyntaxError: Unexpected token C in JSON at position 0 at JSON.parse () at Response.Body.json (body.js:22) at CatchSubscriber.TestService.handleError [as selector]" – Impromptu_Coder Apr 14 '17 at 11:50

1 Answers1

0

There are 4 ways of tackling this:

  1. You can set up a proxy (read this tutorial)

  2. You can run your app through an emulator or a mobile phone (inconvinient)

  3. You can get past CORS issues by installing the cordova Whitelist plugin

  4. You can also try and install the Chrome Allow-Control-Origin extension.

Paul Isaris
  • 414
  • 4
  • 13