2
Failed to load URL: 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:4200' is therefore not allowed access.

Is it possible to fix this from Angular2 without changing the code in server side (Java Spring Controller)?

My code

const headers = new Headers({'Content-Type': 'application/json',
    'Access-Control-Allow-Origin' : '*'
});
return this.http.get(url, {headers: headers})
  .toPromise()
  .then(response => response.json().data as Hero[])
  .catch(this.handleError);
Guerric P
  • 30,447
  • 6
  • 48
  • 86
Krishna
  • 1,089
  • 5
  • 24
  • 38

1 Answers1

4

Your backend seems not to accept cross domain requests.

In order to get it to work on Angular, you have to use a proxy so that your frontend and your backend use the same domain (same host name and same port)

In development mode, you can set up a proxy using a proxy.config.json file. Supposing that your backend is hosted on your-domain.com:80, and your backend requests start with /backend, this file would contain something like

{
    "/backend/*":{
        "target": "your-domain.com",
        "secure": false,
        "logLevel": "debug"
    }
}

Make your development HTTP server use this file by changing the following configuration in your package.json

 "scripts": {
    "start": "ng serve --proxy-config proxy.config.json",
  }

Don't forget to call your backend using requests like http://localhost:4200/backend/... instead of http://your-domain.com/...

In order to get it to work on a remote server, you must set up an HTTP server over your Java web application (for example nginx or Apache) configured to do the same as explained before.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • { "/api/*":{ "target": "https://example.com", "secure": false, "logLevel": "debug" } I have added too headers for http request. still facing the issue } – Krishna Mar 05 '18 at 12:27
  • do you start your frontend using `npm run start` ? (not just `ng serve`) you said you're still facing the issue, I assume you still have an error message about CORS, did you change all of your requests to `http://localhost:4200/api/...` ? – Guerric P Mar 05 '18 at 13:16
  • also there is an unwanted semicolon in your JSON configuration – Guerric P Mar 05 '18 at 13:42
  • I removed that semicolon. did you change all of your requests to http://localhost:4200/api/...? Sorry, I didn't get this. Can u elaborate? – Krishna Mar 05 '18 at 14:13
  • when you make requests to your backend, using `Http` or `HttpClient` depending on which Angular version you are using, at the moment you use `http://example.com/whatever-your-api-exposes` but now you have configured the proxy the new URLs are `http://localhost:4200/api/whatever-your-api-exposes`. You can use relative URLs like `/api/...` so you don't have to specify the host name and port in a configuration file – Guerric P Mar 05 '18 at 14:18
  • It is working. Will we face this --> imagine you could bypass the client and attackers used it to read your banking website while you were logged in.? – Krishna Mar 05 '18 at 14:28
  • if I understand, you wonder if a request between the proxy and the app can be intercepted. When running on a server, the proxy should be set on the server, so the requests between the proxy and the app are internal to your server. Thus there is no risk at all and you don't even need SSL for this data flow – Guerric P Mar 05 '18 at 14:36
  • 1
    ok I just noticed your question was related to @Ferrybig comment. Then the answer is, using a proxy, you keep the protection brought by Access Control headers and your API remains unaccessible to malicious javascript code from other websites – Guerric P Mar 06 '18 at 10:11