1

I am trying to make an Google Maps API JavaScript request from a localhost using Angular 2's HTTP.get() method. In my request I need to add headers and I attempted to do this, but I received this error notice:

https://maps.googleapis.com/maps/api/place/textsearch/json?query=Santa+Cruz&key=MY_KEY. 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:51268' is therefore not allowed access.

All I want to do is enter in a city name and have the response return with a JSON object. Can someone please explain what I am doing wrong here?

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

@Injectable()
export class SearchService {
    dataHere: Object;
    errorMessage: String;

    constructor(private http: Http) { }

    getPlaces(name: String): Observable<any> {
        const url = "https://maps.googleapis.com/maps/api/place/textsearch/json?query=Santa+Cruz&key=MY_KEY";
        let headers = new Headers({ 'Access-Control-Allow-Origin': '*','Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers });

        return this.http.get(url, options)
            .map(r => this.dataHere = r.json())
            .catch((error:any) => Observable.throw(error.json().error));
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

Bugs listed in Web Inspector:

enter image description here

Les Paul
  • 1,150
  • 4
  • 21
  • 42

2 Answers2

1

The CORS toggle Chrome extension is great for development work but you will still run in to the issue when you move to production.

I've spent the last few days trying to find the cleanest solution for this with not much luck. Google do offer a client-side JavaScript library. But to use it, you have to hard-code a script file in index.html which I totally disagree with (think: what if the device doesn't have an internet connection, how would you handle errors?)

I also found that, Google have deprecated JSONP after moving from v2 of the API to v3 which sucks because that would have been the ideal work-around.

Instead, the only real solution I could find was to set up a super-simple NodeJS/Express backend which is configured correctly for CORS and acts as a proxy between your Ionic application and the Google API.

It was the first time I ever tried Node and it wasn't too difficult to set this up. I wrote a guide here: https://www.technouz.com/4674/use-google-places-api-ionic-3-simple-nodejs-backend-heroku/ and also created a sample Git repo here: https://github.com/zuperm4n/super-simple-nodejs

I was having the issue with an Ionic application, but it's the same concept for Angular.

7ahid
  • 171
  • 1
  • 9
-1

The answer to my solution is here. I attempted to make a CORS request from a localhost, so I entered this command in my console:

chrome.exe --disable-web-security

This disables the same origin policy on Google Chrome and allows for API calls. This should NOT be done except for the purposes of making API calls in development with sites you are 100% are safe. I'm sure there are those who would argue it should NEVER be done.

Community
  • 1
  • 1
Les Paul
  • 1,150
  • 4
  • 21
  • 42
  • You could download [Chrome CORS Extension](https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en) and with a slider, you could on/off the 'Access-Control-Allow-Origin'. Your way: entire web-security is off. – xmux Jan 31 '17 at 21:22