Day 33 of #100DaysOfCode: Review CORS
Tags: cors, http, webdev, frontend
Published: 2020-08-17 15:14:44

## Introduction
To use *XmlHttpRequest/Fetch* to get resources from different *origin (scheme + domain + host + port)*, *Cross-Origin Resource Sharing (CORS)* is a policy implemented in the server-side and the browser.

Cross-domain request are always controlled by CORS

1. The Origin header of the request and the Access-Control-Allow-Origin header of the response has to be the same
2. The Access-Control-Allow-Origin header of the response is *

### Origin

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v56g2lhk35wmr415vum8.png)

### First-level domain (Top-level domain)
* Country
  * e.g, `.com (commercial)`, `.org (organizaion)`
* Category
  * e.g., `.ie (ireland)`

### Same-origin policy
1. URLs have the same schema, domain, host, and post
2. The cross-domain requests from JavaScript are usually limited like XMLHttpRequest or Fetch API
3. The cross-domain requests from HTML are usually unlimited like script, img, link, iframe, video

## For CORS, there are two kind of requests.

### 1. Simple request
#### Only use following methods
* HEAD, GET, or POST

#### Only contains following HTTP headers
* Accept
* Accept-Language
* Content-Language
* Content-Type: application/x-www-form-urlencoded、multipart/form-data、text/plain
* Last-Event-ID

#### Example request
```C#
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
   
function callOtherDomain() {
  if(invocation) {    
    invocation.open('GET', url, true);
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}
``` 
* source: https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS

#### Sequence diagram
1. The browser adds origin in the HTTP request header if the request meets the requirements of the simple request
2. The server responses with *Access-Control-Allow-Origin* and resources if the origin is valid.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n1pcflzwblpdr77khoyt.png)

* image source: https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS

### 2.Non-simple request
#### Use other methods
* like DELETE or PUT

#### Contains other HTTP headers
* like Content-Type: application/json

#### Example request

```C#
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
    
function callOtherDomain(){
  if(invocation)
    {
      invocation.open('POST', url, true);
      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
      invocation.setRequestHeader('Content-Type', 'application/xml');
      invocation.onreadystatechange = handler;
      invocation.send(body); 
    }
}
```

* source: https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS

#### Sequence diagram
1. The browser sends pre-flight requests if the request meets the requirements of the non-simple request with the *OPTIONS* method
2. The server responses with *Access-Control-Allow-Origin* and *Access-Control-Allow-Methods* if the origin is valid.
3. The browser sends the real request to the server with *origin*
4. The server responses with *Access-Control-Allow-Origin* and resources

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ykkp6j3wtmu8lltcq5op.png)

* image source: https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS

That's it!

## Articles
There are some of my articles. Feel free to check if you like! 
* My blog-posts for software developing: https://medium.com/a-layman
* My web resume: https://jenhsuan.github.io/ALayman/cover.html
* Facebook page: https://www.facebook.com/imalayman
* My latest side project - Daily Learning: https://daily-learning.herokuapp.com/

## References
* [前端 | 浅谈preflight request](https://www.jianshu.com/p/b55086cbd9af)
* [跨來源資源共用（CORS）](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS)
* [跨域资源共享 CORS 详解](https://www.ruanyifeng.com/blog/2016/04/cors.html)