3
  1. I have a JavaScript application let's say that it is deployed on portal.example.com.
  2. That includes a <script> tag that loads source that is served from assets.example.com.
  3. That JavaScript file makes an HTTP request to an API on admin.example.com

This API request is erroring due to CORS pre-flight failing.

Failed to load http://admin.example.com/v0/user/navigation: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://portal.example.com' is therefore not allowed access.

The actual OPTIONS request is as below

OPTIONS /v0/user/navigation HTTP/1.1
Host: admin.example.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://portal.example.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Access-Control-Request-Headers: authorization,x-correlation-id,x-user-domain
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,en-GB;q=0.8

The actual OPTIONS response is as below

HTTP/1.1 200
Allow: GET
Access-Control-Allow-Headers: authorization,x-correlation-id,x-user-domain
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: http://portal.example.com
Vary: Origin
Content-Length: 0
Date: Tue, 20 Feb 2018 12:12:19 GMT
Set-Cookie: 97d2c19dadc3933a73dce9bec0748df1=5a15895c5e0f5b526c177132cb4aa666; path=/; HttpOnly
Cache-control: private
X-RBT-SCAR: 10.127.48.7:777511903:1000

I think the issue is because the request is actually coming from a script served from assets.example.com is making the request. So I should be returning Access-Control-Allow-Origin: http://assets.example.com in the OPTIONS response. However, I have followed the advice of W3C.

The Access-Control-Allow-Origin header indicates whether a resource can be shared based by returning the value of the Origin request header, "*", or "null" in the response.

So am I misunderstanding CORS, or is the browser sending the Origin of the main executing URL and not the URL of the script making the request?

UPDATED

GET response

HTTP/1.1 200
X-Correlation-Id: 8978b245-081a-4c4a-b4c9-73f2920ab55c
Content-Type: application/vnd.example+json
Transfer-Encoding: chunked
Date: Tue, 20 Feb 2018 13:22:39 GMT
Set-Cookie: 97d2c19dadc3933a73dce9bec0748df1=dc4e3543c3071d752959e7176c5e4d29; path=/; HttpOnly
Cache-control: private
X-RBT-SCAR: 10.127.48.7:778160108:2000
baynezy
  • 6,493
  • 10
  • 48
  • 73
  • Can you please provide the headers of the `GET` response? – Alex Michailidis Feb 20 '18 at 13:19
  • Your setup looks correct. What I'm about to suggest is going to be a stretch. On your server side where you setup CORS, first make sure that the spelling for the origin is correct. If it is, then take `http://portal.example.com` and delete the entire string (and the first characters before and after it) then re-type it in manually. I've seen instances where people copy and pasted some text that included some special unicode character that went undetected and caused some havoc. – Joseph Feb 20 '18 at 13:21
  • @alex-rokabilis I have updated the question – baynezy Feb 20 '18 at 13:25

2 Answers2

5

No 'Access-Control-Allow-Origin' header is present on the requested resource. That means that 'Access-Control-Allow-Origin' header is missing, not that your domain is not allowed.

If you didn't have permission, you would see something like

The 'Access-Control-Allow-Origin' header has a value 'http://www.example.com' that is not equal to the supplied origin.

So, to solve your problem you need to configure your GET response to provide the necessary CORS headers as well as the OPTIONS response.

In your edited question the GET response headers doesn't provide anything for the Access-Control-* so that's why you get the error!

Alex Michailidis
  • 4,078
  • 1
  • 16
  • 35
1

Your CORS preflight is not failing - you're getting a 200 response and all the required CORS response headers...

However, you're not returning any of the CORS response headers in the GET response - that is what's failing. At a minimum, you need to return a Access-Control-Allow-Origin response header which matches the one returned in the OPTIONS response.

So just include this in your GET response and you'll be fine:

Access-Control-Allow-Origin: http://portal.example.com

Finally, the Origin request header is added by the browser, and trust me - it's correct. But it really doesn't matter what value is sent, since all that is required is that the Access-Control-Allow-Origin response header matches the Origin request header (either by having a value of '*' or exactly matching the Origin value).

roryhewitt
  • 4,097
  • 3
  • 27
  • 33