-1

I have to get data from a json hosted on an external server online. The url look like http://example.com/path/to/resource.json. I can read this json via browser, postman and some other tool.

But when I try to get the data from an Angular 11 application I get the CORS error:

Access to XMLHttpRequest at 'http://example.com/path/to/resource.json'
from origin 'http://localhost:4200' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

The code is literally just the GET with the HttpClient class:

this.http.get('http://example.com/path/to/resource.json)'

What I tried was to configure the proxy but without success:

// proxy.conf.json
{
    "/path": {
        "target": "http://example.com",
        "secure": false
    }
}

// angular.json
"serve": {
  [...]
  "options": {
    [...]
    "proxyConfig": "proxy.conf.json"
  },
  [...]
},

Both files are in the root folder of the project.

I don't have control on the server, so I cannot allow CORS on it or change other settings but I don't think this is the issue.

I don't understand why I can access resources via many tools but I always have problems to do the same with Angular.

chenny
  • 385
  • 2
  • 10
  • 32
  • Since you do not have control of the server, I suggest looking at this post. https://stackoverflow.com/questions/35588699/response-to-preflight-request-doesnt-pass-access-control-check/35588856#35588856 – E. Maggini Jan 29 '21 at 22:53
  • CORS is actually not an Angular issue - it is the browser that requires it (and also the browser that performs the OPTIONS preflight). For your proxy to work, you'll have to use a relative path so this.http.get('/path/to/resource.json)' – MikeOne Jan 29 '21 at 22:57
  • Try to use an extension while running the app. Such as this one: Allow CORS: Access-Control-Allow-Origin – jviudes Jan 30 '21 at 02:20
  • So this is not an Angular issue, it's just some browser block. I tried a Chrome extension and it works but I can use it just for development. Is there a way to make it work from Angular code without browser extension? I need to show the project to someone else and I cannot force to install the browser extensions. Why with the other tools I can get the resource without problems but it doesn't work with Angular using `HttpClient`? – chenny Jan 31 '21 at 04:46

1 Answers1

0

To cite from the MDN Web Docs on CORS:

Who should read this article?

Everyone, really.

I agree and strongly suggest to read that page. It will help you greatly to understand what is going on and why and how to approach this correctly.

I don't understand why I can access resources via many tools but I always have problems to do the same with Angular.

First: this is not an issue with Angular but simply a security feature of the browser.

But in short: calling the API from your (Angular) web app in the browser results in a cross-origin request since the web app is accessed on a different origin (=domain) than the external API. This will cause the browser to first trigger a preflight request to ask the external API server whether it allows a cross-origin request from your web app. If that's not the case the request is blocked by the browser.

When you access the API directly in the browser or similar tools the URL is accessed directly and the browser/tool does not issue a preflight request as with a CORS request.

There are basically two ways to solve this:

  1. Configure CORS on the API server respectively - which got eliminated since you have no control over the API server
  2. Use a proxy server, e.g. the Angular proxy

In the first case you wouldn't have to change anything in your frontend code, in the latter case you need to change the URL in the frontend to access the proxy server instead, i.e.

this.http.get('http://example.com/path/to/resource.json')

becomes

this.http.get('/path/to/resource.json')

(given your proxy runs under the same origin as your Angular app)

But again, I'd suggest to read the MDN Web Docs on CORS for a better understanding!

acran
  • 1,795
  • 5
  • 20