CORS
CORS allows cross-domain HTTP data exchange, which means a page running at origin A can send/receive data from a server at origin B. CORS is abundantly used in web applications where web fonts, CSS, documents, and so on are loaded from different origins, which may not be of the origin where the resources are actually stored. Most content delivery networks (CDNs) which provide resource-hosting functionality typically allow any website or origin to interact with themselves.
CORS works by adding a new HTTP header that allows the web server to speak up a list of whitelisted domains that are allowed to connect and interact with the server. This thing is also browser enforced; the browser reads the header and processes accordingly.
The following flow chart shows the CORS flow at different positions:
CORS headers
There are less than a dozen HTTP headers that are related to CORS but I'll try to explain a few commonly used CORS headers:
- Access-Control-Allow-Origin: This is a response header; as soon as a request is made to the server for exchanging data, the server responds with a header that tells the browser whether the origin of the request is listed inside the value of this response. If the header is not present or the response header does not contain the request origin inside the header, then the request is dropped and a security error is raised (as seen earlier in the last section), otherwise the request is processed.
Example:
Access-Control-Allow-Origin: http://api.example.com
- Access-Control-Allow-Methods: This is another response header; the server responds with this header and instructs the browser to check for allowed HTTP methods mentioned inside it. If the server only allows GET and a POST request is initiated then it will be dropped if not mentioned in this list.
Example:
Access-Control-Allow-Methods: GET
- Origin: This is a request header which tells the server from which domain origin the request was attempted. The origin header is always sent alongside cross-domain requests.
Example:
Origin: http://example.com
Pre-flight request
A pre-flight request is just a normal HTTP request that happens before the actual cross-domain communication. The logic behind this is to ensure the client and server are fully compatible (protocol, security, and so on) with each other before the data is actually exchanged. If they are not, then the relevant error is raised.
Please keep that in mind that a pre-flight request only triggers if:
- Custom HTTP headers are sent
- The body MIME-type is different than
text/plain
- The HTTP method is different than GET or POST
The following is a typical pre-flight request-response pair:
Request:
OPTIONS / HTTP/1.1 Origin: http://api.user.com Access-Control-Request-Method: PUT Host: api.example.com Accept-Language: en-US Connection: keep-alive User-Agent: Browser
Response:
HTTP/1.1 204 No Content Access-Control-Allow-Origin: http://api.user.com Access-Control-Allow-Methods: GET, POST, PUT Content-Type: text/html; charset=utf-8
Simple request
A simple CORS request is similar to a pre-flight request without the initial capability exchange sequence occurring. In a typical simple CORS request, the following sequence happens:
Request: http://example.com – Origin A
Response: http://cdn.prakharprasad.com – Origin B
- Origin A attempts to access the home page of a CDN running at origin B,
http://cdn.prakharprasad.com
, using CORS. - Origin A sends a GET request to the Origin B web server.
- The Origin B server responds with Access-Control-Allow-Origin.