15

I am struggling with this issue today as I am implementing a cross-site API call. The worst thing is it works well from my local environment but once on heroku, it fails with the following error:

XMLHttpRequest cannot load https://restcountries.eu/rest/v1/all. Request header field X-XSRF-TOKEN is not allowed by Access-Control-Allow-Headers in preflight response.

Here is the function triggering the call:

  let observable = this._http
    .get(GEO_API_URL + query)
    .map(response => response.json())
    .do(val => {
      this.cache = val;
      observable = null;
    })
    .share();

  return observable;

Any idea ?

Thanks.

kfa
  • 2,106
  • 4
  • 17
  • 22
  • That needs to be configured no the server and is not related to Angular2. See also http://stackoverflow.com/questions/10143093/origin-is-not-allowed-by-access-control-allow-origin – Günter Zöchbauer Jul 26 '16 at 12:33
  • Thanks for your answer Günter. I know it's not Angular but there should be some kind of workaround ? But when I try to replace the Access-Control-Request-Headers, it says "Refused to set unsafe Header". – kfa Jul 26 '16 at 12:36
  • I don't know where you replace the header and I don't know what workaround you mean. Angular is not involved in this, the preflight request is created by your browser not by Angular. Only after the response to the preflight request contains the correct headers, the browser is doing the actual request initiated by Angular. – Günter Zöchbauer Jul 26 '16 at 12:40
  • Thanks for the follow-up. I didn't say it was angular, I mentioned angular on the title because that's the technology I'm using here. It works from local but once on heroku it fails... That's it. – kfa Jul 26 '16 at 12:51
  • If you access a different URL (even when only the port is different) the browser requires the CORS headers. You'll have to look up how to configure them on Heroku. – Günter Zöchbauer Jul 26 '16 at 12:53

5 Answers5

46

Had the same issue.
In my case the reason was that in my Chrome cookies was saved X-XSRF-TOKEN field. And somehow Chrome added header 'Access-Control-Request-Headers: x-xsrf-token' to OPTION request. In Firefox the same page works fine, in incognito mode Chrome - too.
So I've just delete this cookies field (X-XSRF-TOKEN) and that's all.

Zakhar G
  • 469
  • 5
  • 9
12

In my case I had to add the 'x-xsrf-token' value to 'Access-Control-Allow-Headers' header:

header('Access-Control-Allow-Headers: Content-Type, x-xsrf-token')

see AngularJS: POST Data to External REST API

Community
  • 1
  • 1
LeonardoX
  • 1,113
  • 14
  • 31
  • I have an application that has X-XSRF-TOKEN as a default for all requests. This is the easiest way to allow the CORS request to go through. – JoeGalind Nov 17 '18 at 13:11
2

I cleared cookies, this solved problem.

Vasyl Petrov
  • 360
  • 2
  • 9
0

this helped me in java (expose the headers and then include in the allow headers). This will then show in your HttpResponse object:

response.addHeader("Access-Control-Expose-Headers", "header1");
response.addHeader("Access-Control-Expose-Headers", "header2");
    response.addHeader("Access-Control-Expose-Headers", "header3");
                response.addHeader("Access-Control-Allow-Headers", "Origin, header1, header2, header3, X-Requested-With, Content-Type, Accept");
arn-arn
  • 1,328
  • 1
  • 21
  • 31
0

The reason is that x-xsrf-token keyword is not in response header Access-Control-Allow-Headers.

I solved this problem in java using following solution:

rsp.setHeader("Access-Control-Allow-Methods", "GET,HEAD,POST,OPTIONS,PUT,DELETE,TRACE,CONNECT");
                rsp.setHeader("Access-Control-Allow-Headers", "cache-control,content-type,hash-referer,x-requested-with, x-xsrf-token");
                if ("OPTIONS".equals(req.getMethod())) {
                    rsp.setStatus(HttpServletResponse.SC_OK);
                    return;
                }

Manoj
  • 2,059
  • 3
  • 12
  • 24