CORS
Access to fetched has been blocked by CORS policy
Every developer will feel frustrated when they see that big red error in the console! 😬Although there are some ways to get rid of this error quickly, let's not take it for granted today! Instead, let’s see what CORS is actually doing and why it’s actually our friend
On the front end, we often want to display data located elsewhere! Before we can display this data, the browser must first make a request to the server to get the data! The client sends an HTTP request that contains all the information the server needs in order to send the data back to the client
Suppose we try to www.mywebsite.com
from located at api.website.com
We sent an HTTP request to the server, and the server responded with the JSON data we requested
Let's try the exact same request, but from another domain. www.mywebsite.com
We are not making a request from, but from the website located at www.anotherdomain.com
We sent the exact same request, but this time the browser showed us a weird error, we just saw the role of CORS, what will happen to this error, and what does it mean
Same Origin Policy
The network enforces what is called the same-origin policy. By default, we can only access resources that are in the same source as the request source! https://mywebsite.com/image1.png
For example, it is perfectly possible to load an image located in
When the resource is located in different (sub)domains, protocols or ports, it is cross-origin
Why is there a same-origin policy?
Suppose that the same-origin policy does not exist, and you accidentally clicked on one of the many virus links sent to you on Weibo. This link will redirect you to an "evil website" that embeds an iframe, which will load your bank's website and successfully log in through some set cookies
The developer of this "evil website" allowed the website to access this iframe and interact with the DOM content of your bank website in order to send money to their account on your behalf!
This is a huge security risk! We don’t want anyone to have access to everything
Fortunately, the same-origin policy helped us here! This strategy ensures that we can only access resources from the same source
In this case, the source www.evilwebsite.com
tried to use the same-origin policy from www.bank.com
to prevent this from happening, and to ensure that the developers of the evil website could not just access our bank data
Client CORS
Although the same-origin policy actually only applies to scripts, browsers "extend" this policy for JavaScript requests: by default, we can only access resources from the same source
We often need to access cross-domain resources. Maybe our front-end needs to interact with our back-end API to load data? In order to safely allow cross-domain requests, the browser uses a mechanism called CORS
CORS stands for cross-domain resource sharing. Although browsers do not allow us to access resources located in different sources, we can use CORS to slightly change these security restrictions while still ensuring that we access these resources safely
User agents (such as browsers) can use the CORS mechanism to allow cross-domain requests based on the value of certain CORS-specific headers in the HTTP response, otherwise these requests will be blocked
When a cross-domain request is made, the client will automatically add an additional header to our HTTP request: Origin
. The value of Originheader
is the source of the request
In order for the browser to allow access to cross-domain resources, it needs certain headers from the server response, which specify whether this server allows cross-domain requests
Server CORS
As a server developer, we can ensure that cross-domain requests are allowed by adding additional standard Access-Control-*
headers in the HTTP response. These headers all start with headers. Based on the value of these CORS response headers, the browser is now Can allow certain cross-domain responses, which are usually blocked by the same-origin policy
Although we can use multiple CORS headers, browsers need one header to allow cross-origin resource access: Access-Control-Allow-Origin
The value of this header specifies which sources are allowed to access the resources they request from the server
If we are developing a server that should be accessible at https://mywebsite.com, we can add the value of the domain to the Access-Control-Allow-Origin header
This header has now been added to the response that the server sends back to the client. The same policy origin by adding this header will no longer restrict us from not being able to receive resources that are located at the origin of https://api.mywebsite.com
if we make a request from https://mywebsite.com
The CORS mechanism in the browser checks whether the value of Access-Control-Allow-Originheader is equal to the value sent by Origin request
In this case, the source of our request is https://www.mywebsite.com
, which is listed in the Access-Control-Allow-Origin
response header
We can successfully receive cross-domain resources! So what happens when we try to access these resources from a source not listed in the Access-Control-Allow-Origin
header?
CORS caused notorious errors, which can be frustrating at times! But now we actually see that it makes perfect sense
The'Access-Control-Allow-Origin' header has a value
'https://www.mywebsite.com' that is not equal
to the supplied origin.
In this case, the source provided is https://www.anotherwebsite.com
. However, the server did not provide this source in the allowed source list of the Access-Control-Allow-Origin
header! CORS successfully intercepted the request, and the obtained data cannot be accessed in our code
CORS also allows us to add the wildcard character * as the value of the allowed source. This means that requests from all sources should have access to the requested resource
Access-Control-Allow-Origin
is one of the many CORS headers we can provide. Server developers can extend the server’s CORS policy to (disallow) allow certain requests
Another common title is the Access-Control-Allow-Methods
title! CORS only allows cross-domain requests sent using the listed methods
In this case, only requests with GET, POST, or PUT methods are allowed! Other methods such as PATCH or DELETE will be blocked
Speaking of PUT, PATCH and DELETE requests, CORS actually handles these requests differently! 🙃 These "non-simple" requests initiate a thing called preflight request
Preflight request
CORS has two types of requests: simple requests and preflight requests. Whether the request is simple or preflight depends on some values in the request
When the request is a GET or POST
method and does not have any custom headers, the request is simple! Any other requests, such as requests with PUT
, PATCH
or DELETE
methods, will be pre-checked
Before sending the actual request, the client will generate a preflight request! The preflight request contains information about the actual request we are about to execute in its Access-Control-Request-*
header
This provides the server with information about the actual request that the browser is trying to make: what is the method of the request, what are the additional headers, etc.
The server receives this preflight request and sends an empty HTTP response with the server's CORS header! The browser receives the preflight response, contains no data other than the CORS header, and checks whether the HTTP request should be allowed
If this is the case, the browser will send the actual request to the server, and the server will respond with the data we requested
However, if this is not the case, CORS will block the preflight request, and the actual request will never be sent. The preflight request is a good way to prevent us from accessing or modifying resources on servers that do not have any CORS policies enabled (yet)! The server is now protected from potentially unwanted cross-domain requests
In order to reduce the number of round trips to our server, we can cache the preflight response by adding a header to the Access-Control-Max-AgeCORS request! We can cache the preflight response in this way, and the browser can use it instead of sending a new preflight request
Certificate
By default, cookies, authorization headers, and TLS certificates are only set on same-origin requests! However, we may want to use these credentials in cross-domain requests. Maybe we want to include cookies in the request, the server can use these cookies to identify the user
Although CORS does not contain credentials by default, we can change it by adding the Access-Control-Allow-Credentials
CORS header
If we want to include cookies and other authorization headers in our cross-domain request, we need to set the withCredentials
field to true in the request
and add the Access-Control-Allow-Credentials
header to the response
That's it, that's it! We can now include credentials in cross-domain requests
Although I think we all agree that CORS errors can be frustrating at times, it is surprising that it allows us to make cross-domain requests safely in the browser
Post comment 取消回复