1

I'm getting this error:

XMLHttpRequest cannot load API_URL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

while calling a remote API from localhost. I do not have access to the API server, so I can't allow for CORS on the server side. Here is how I'm calling the API from my Angular service:

this.http.get(url)
         .map(response  => response.json())
         .subscribe(data => this.myData.push(data));

I'd like to use the member myData afterwards. When looking at chrome's dev tools, I see a 200 message in the networks tab. It also shows the correct JSON Response, but I get the above error in the console and can't use the data.

I've been searching how to fix this. But modifying browser options and server setting is not an option. If possible I want to avoid making a proxy server as well. Also this is the first time I'm using Angular 2, so I don't have a solid understanding of how things work; so it's possible that I should be making requests in a totally different way.

I also tried to add the setting Access-Control-Allow-Origin to my header as follows:

let headers = new Headers();
headers.append('Access-Control-Allow-Headers', 'Access-Control-Allow-Origin');
headers.append('Access-Control-Allow-Origin', this.serverName);
this.http.get(url , {headers: headers})
    .map(response  => response.json())
    .subscribe(data => this.myData.push(data));

But that resulted in this error:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

This time the response was empty. Looking at the request header I don't see Access-Control-Allow-Headers and Access-Control-Allow-Origin set the the values of the .append calls. Am I setting those header options correctly??

Using jsonp instead of http was not helpful either as the application type on the header is set to json:

refused to execute script from API_URL because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

I'd appreciate if you explain a fix in details as I have been unable to follow any solution on the web, perhaps I'm missing some important assumption or must-know.

alamoot
  • 1,966
  • 7
  • 30
  • 50
  • 1
    Your only option if you want to make the request from your frontend JavaScript code is to use a CORS proxy as described in https://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource/42744707#42744707. Otherwise you need to make the request from your backend code instead. And the reason that trying to set the Access-Control-* headers from the client side the way you’re doing doesn’t work is, those headers are *response* headers that must be sent from server side, not request headers you can send from the client side. – sideshowbarker Jun 18 '17 at 21:21
  • @sideshowbarker that explains the weird header behavior. – alamoot Jun 18 '17 at 21:31

2 Answers2

2

Access-Control-Allow-Origin is a response header, not a request header you need to fix the permission in your backend (i use nodejs). so You must create cors.js file that contains all necessary permissions.

function crosPermission(){
  this.permission=function(req,res,next){
    res.header('Access-Control-Allow-Origin','*');
    res.header('Access-Control-Allow-Headers','Content-Type');
    res.header('Access-Control-Allow-Methods','GET','POST','PUT','DELETE','OPTIONS');
    next();
  }
}

module.exports= new crosPermission();

next step You need to add some line in your app.js

var cors=require('./cors');
app.use(cors.permission)
Bettaibi Nidhal
  • 215
  • 3
  • 8
1

This is due to the security features of browsers where they enforce the same origin. See Wikipedia: https://en.wikipedia.org/wiki/Same-origin_policy

So it isn't related to Angular. The proxy server you mention is one way around the problem. But you can't stop the browser from enforcing this rule nor should you try.

Rob Zuber
  • 131
  • 3
  • 1
    Hey Rob, welcome to SE. Your answer is not a solution to the problem, rather it's just extra info regarding the situations. These type of answers should be posted as comments. – alamoot Jun 18 '17 at 18:48