CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”.
It allows browsers to issue XMLHttpRequest requests across source servers, overcoming the limitation that AJAX can only be used in the same source.
This article details the internal mechanism of CORS.
A list,
CORS requires both browser and server support. Currently, all browsers support this function, and Internet Explorer cannot be lower than Internet Explorer 10.
The entire CORS communication process is completed automatically by the browser without user participation. For developers, CORS communication is no different from same-origin AJAX communication, and the code is exactly the same. As soon as the browser discovers that an AJAX request crosses the source, it automatically adds some additional headers, and sometimes an additional request, but the user doesn’t feel it.
Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, cross-source communication is possible. (that is, the page of domain A wants to access the page of domain B, just need to add the backend response header in the server background of domain B to allow domain request! Add the following Settings to the requested Response header and you have cross-domain access!
Two kinds of requests
Browsers classify CORS requests into two categories: Simple request and not-so-simple Request.
As long as the following two conditions are met, it is a simple request.
(1) Request method is one of the following three methods:
- HEAD
- GET
- POST
(2) HTTP headers do not exceed the following fields:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-type: is limited to three values
application/x-www-form-urlencoded
,multipart/form-data
,text/plain
Any request that does not meet both conditions is a non-simple request.
Browsers treat these two requests differently.
3. Simple requests
3.1 Basic Process
For simple requests, the browser issues CORS requests directly. Specifically, add an Origin field to the header information.
As an example, the browser automatically adds an Origin field to the header when it realizes that the cross-source AJAX request is a simple one.
GET /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com Accept-language: en-us Connection: Keep alive - the user-agent: Mozilla / 5.0...Copy the code
In the header above, the Origin field specifies the source (protocol + domain + port) from which the request came. Based on this value, the server decides whether to approve the request or not.
If Origin does not specify a licensed source, the server will return a normal HTTP response. The browser realizes that the response header does not contain the Access-Control-Allow-Origin field (more on that below), and it throws an error that is caught by XMLHttpRequest’s onError callback. Note that this error cannot be identified by the status code, because the status code for the HTTP response might be 200.
If Origin specifies a domain name within the license, the server returns a response with several additional header fields.
Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8 Copy the code
In the header above, there are three fields related to CORS requests, all beginning with Access-Control-.
(1) Access – Control – Allow – Origin
This field is required. Its value is either the value of the Origin field at the time of the request, or an *, indicating acceptance of requests for any domain name.
(2) Access – Control – Allow – Credentials
This field is optional. Its value is a Boolean value indicating whether cookies are allowed to be sent. By default, cookies are not included in CORS requests. If set to true, the server explicitly approves that cookies can be included in the request and sent to the server. This value can only be set to true if the server does not want the browser to send cookies.
(3) the Access – Control – Expose – Headers
This field is optional. In CORS requests, the getResponseHeader() method of the XMLHttpRequest object takes only six basic fields: Cache-control, Content-language, Content-Type, Expires, Last-Modified, Pragma. If you want to get other fields, you must specify access-Control-expose-headers. The above example specifies that getResponseHeader(‘FooBar’) can return the value of the FooBar field.
3.2 withCredentials attribute
As mentioned above, CORS requests do not send cookies and HTTP authentication information by default. To send cookies to the server, specify the access-Control-allow-credentials field with the server’s permission.
Access-Control-Allow-Credentials: true Copy the code
On the other hand, the developer must turn on the withCredentials attribute in the AJAX request.
var xhr = new XMLHttpRequest(); xhr.withCredentials = true; Copy the code
Otherwise, the browser won’t send a Cookie, even if the server agrees to do so. Or, if the server asks for a Cookie, the browser won’t handle it.
However, if the withCredentials setting is omitted, some browsers still send cookies together. In this case, you can explicitly disable the withCredentials.
xhr.withCredentials = false; Copy the code
Note that access-Control-allow-Origin cannot be set to an asterisk if cookies are to be sent, and must specify an explicit domain name consistent with the requested web page. At the same time, cookies still follow the same origin policy, only the Cookie set with the server domain name will be uploaded, cookies of other domain names will not be uploaded, and (cross-source) document. Cookie in the original web page code can not read cookies under the server domain name.
4. Non-simple requests
4.1 Precheck request
Non-simple requests are requests that have special requirements on the server, such as the request method being PUT or DELETE, or the content-Type field being of Type Application/JSON.
CORS requests that are not simple requests are preceded by an HTTP query request, called a “preflight” request.
The browser asks the server if the domain name of the current web page is on the server’s license list, and what HTTP verb and header fields can be used. The browser issues a formal XMLHttpRequest request only if it receives a positive response; otherwise, an error is reported.
The following is a JavaScript script from the browser.
var url = 'http://api.alice.com/cors'; var xhr = new XMLHttpRequest(); xhr.open('PUT', url, true); xhr.setRequestHeader('X-Custom-Header'.'value'); xhr.send(); Copy the code
In the code above, the HTTP request is PUT and sends a Custom Header x-custom-header.
The browser realizes that this is not a simple request and automatically issues a “pre-check” request, asking the server to confirm that it is ok to do so. Here is the HTTP header for this “precheck” request.
OPTIONS /cors HTTP/1.1 Origin: http://api.bob.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header Host: api.alice.com Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0... Copy the code
The request method for the “precheck” request is OPTIONS, indicating that the request is being queried. In the header information, the key field is Origin, indicating which source the request came from.
In addition to the Origin field, the precheck request header contains two special fields.
(1) Access – Control – Request – Method
This field is required to list which HTTP methods are used by the browser for CORS requests, in this example PUT.
(2) Access – Control – Request – Headers
This field is a comma-separated string that specifies the additional Header field to be sent by a browser CORS request, x-custom-header in the example above.
4.2 Response to precheck request
After receiving the precheck Request, the server checks the Origin, access-Control-request-method, and access-Control-request-headers fields and confirms that cross-source requests are allowed, it can respond.
HTTP/1.1 200 OK Date: Mon, 01 Dec 2008 01:15:39 GMT Server: Apache/2.0.61 (Unix) Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Content-Length: 0 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/plain Copy the code
In the HTTP response above, the key is the Access-Control-Allow-Origin field, which indicates that http://api.bob.com can request data. This field can also be set to an asterisk to indicate approval of any cross-source request.
Access-Control-Allow-Origin: * Copy the code
If the browser denies the “precheck” request, it will return a normal HTTP response, but without any CORS related header fields. At this point, the browser decides that the server did not approve the precheck request, and therefore fires an error that is caught by the ONError callback function of the XMLHttpRequest object. The console will print the following error message.
XMLHttpRequest cannot load http://api.alice.com. Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin. Copy the code
Other CORS related fields that the server responds to are as follows.
Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Allow-Credentials: true Access-Control-Max-Age: 1728000 Copy the code
(1) Access – Control – Allow – the Methods
This field is required, and its value is a comma-separated string indicating all methods supported by the server for cross-domain requests. Notice that all supported methods are returned, not just the one requested by the browser. This is to avoid multiple “pre-check” requests.
(2) Access – Control – Allow – Headers
The access-Control-allow-HEADERS field is required if the browser Request includes the access-Control-request-HEADERS field. It is also a comma-separated string indicating all header information fields supported by the server, not limited to those requested by the browser in precheck.
(3) the Access – Control – Allow – Credentials
This field has the same meaning as a simple request.
(4) the Access – Control – Max – Age
This field is optional and specifies the validity period of the precheck request, in seconds. In the result above, the validity period is 20 days (1728000 seconds), which allows the response to be cached for 1728000 seconds (20 days), during which time another precheck request is not issued.
4.3 Normal Browser Requests and Responses
Once the server passes the “precheck” request, every subsequent normal BROWSER CORS request will have the same Origin header field as a simple request. The server also responds with an Access-Control-Allow-Origin header field.
The following is a normal CORS request for the browser after the “precheck” request.
PUT /cors HTTP/1.1 Origin: http://api.bob.com Host: api.alice.com X-Custom-Header: value Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0... Copy the code
The Origin field in the header above is automatically added by the browser.
The following is a normal response from the server.
Access-Control-Allow-Origin: http://api.bob.com Content-Type: text/html; charset=utf-8 Copy the code
In the header above, the access-Control-Allow-Origin field is mandatory for each response.
V. Comparison with JSONP
CORS serves the same purpose as JSONP, but is more powerful than JSONP.
JSONP supports only GET requests, and CORS supports all types of HTTP requests. JSONP has the advantage of supporting older browsers and being able to request data from sites that do not support CORS.
Note: This article is reprinted (original link)