(CORS C# ASP.NET Core) Why cross-origin requests (CORS) fail and why they succeed?

In the previous tutorial, we demonstrated how a browser blocks cross-origin calls. So you must surely be wondering why cross-origin requests to CDN-hosted CSS files and fonts succeed. What's behind that success? Why do browsers permit some requests and block others? In this tutorial, we examine the reasons behind this. It will help us allow cross-origin requests in our ASPNET Core apps!
(Rev. 30-Sep-2022)

Categories | About |     |  


The header called "Origin"

One of the HTTP headers that plays a role in cross-origin requests is called "Origin."

When a browser makes a cross-origin request to a different server, it adds a header called Origin with its value set equal to the URL of the website that provided the current HTML page.

We can simulate this behavior with curl, a tool that comes pre-installed on a Windows 10 computer. For this, open the windows command prompt and type the following command: curl -I bootstrapcdn -H "Origin:https://hoven.in"

// type in one single line 

curl  -I  https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/

     -H  "Origin:https://hoven.in"

Option I sets the URL to that of the public Bootstrap CDN that allows its CSS files to be fetched cross-origin. We all know that it happens! Because Bootstrap-supported websites are available all over the internet. The second option, H, adds a header called Origin, with its value set to a third-party website.

Hit Enter, and allow the response to be received. We get a long list of headers. First of all, the response indicates success with 200 OK. After that we have the usual Headers like Date, Content-Type and Connection. The next two need a closer look.

// list of headers is truncated 

HTTP/1.1 200 OK
Date: Fri, 12 Aug 2022 14:47:55 GMT
Content-Type: text/css; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: *
Cache-Control: public, max-age=31536000 
Cross-Origin-Resource-Policy: cross-origin
Server: cloudflare

  1. Access-Control-Allow-Origin: this header tells the browser that the server allows cross-origin requests from all types of origins. It is, in fact, the main reason why this CDN can serve so many websites around the world!
  2. Access-Control-Expose-Headers: this header tells the browser that the server accepts all types of headers sent by the requesting clients. We'll discuss it later.

When this header - Access-Control-Allow-Origin - is sent by the server, and when it permits a cross-origin request from the current website, the browser allows the response to be presented to the caller. So now it must be clear why cross-origin requests succeed!

Video Explanation (see it happen!)

Please watch the following youtube video:

Run the ASPNET Core Project

Next let's run our project to see if the server is sending these headers.

Run the project and allow the home page to open.

Now again open the command prompt and type the following command: curl -I localhost:7276/check -H "Origin:https..."

curl -I https://localhost:7276/check -H "Origin:https://hoven.in"

Hit the Enter key. The server sends the following headers -

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Fri, 12 Aug 2022 15:24:57 GMT
Server: Kestrel
Transfer-Encoding: chunked

We observe that the Access-Control-Allow-Origin header is absent - the server hasn't sent it! It's now clear why the browser blocked the cross-origin request in the previous tutorial.

NOTE: Cross-origin requests are blocked by browsers - not by tools like curl, postman and HttpClient api of C#.

In the next tutorial we shall see how to modify our ASPNET Core app to enable cross-origin requests. Thanks!

This Blog Post/Article "(CORS C# ASP.NET Core) Why cross-origin requests (CORS) fail and why they succeed?" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.