It allows browsers to make requests to cross source servers, XMLHttpRequest
overcoming the limitations of Ajax being used only in the same homology.
This paper introduces the internal mechanism of cors in detail.
(Photo description: Taken in the UAE Ain (Al Ain) Oasis Park)
First, Introduction
Cors requires both browser and server support. Currently, all browsers support this feature, IE can not be less than IE10.
The entire cors communication process, is the browser automatically completes, does not need the user to participate. For developers, Cors Communications are no different from homology Ajax communications, and the code is exactly the same. Once the browser discovers the Ajax request cross source, it will automatically add some additional header information, and sometimes an additional request, but the user will not feel.
Therefore, the key to realize cors communication is the server. As long as the server implements the Cors interface, it can communicate across sources.
II. two types of requests
The browser divides the cors request into two categories: simple request and not simple request (Not-so-simple requests).
As long as the following two major conditions are met, it is a simple request.
(1) The request method is one of the following three methods:
Headgetpost
(2) HTTP header information does not exceed the following several fields:
Acceptaccept-languagecontent-languagelast-event-idcontent-type: Limited to three values application/x-www-form-urlencoded
, multipart/form-data
text/plain
If the above two conditions are not met at the same time, it is not a simple request.
The browser's handling of these two requests is not the same.
Three, simple request 3.1 basic process
For simple requests, the browser issues a cors request directly. Specifically, in the header information, add a Origin
field.
The following is an example, the browser found that the cross-source Ajax request is a simple request, automatically in the header information, add a Origin
field.
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
In the header information above, the Origin
field is used to indicate which source (protocol + domain + port) This request originated from. Based on this value, the server decides whether to agree to this request.
If Origin
the specified source is not within the scope of the license, the server returns a normal HTTP response. The browser found that the header information for this response did not contain a Access-Control-Allow-Origin
field (see below) to know that an error occurred, thus throwing an error that was XMLHttpRequest
captured by the onerror
callback function. Note that this error cannot be identified by the status code, because the status code of the HTTP response may be 200.
If the Origin
specified domain name is within the license range, the response returned by the server will have a few more header information fields.
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
Of the header information above, there are three fields associated with the cors request, all with the Access-Control-
beginning.
(1) Access-control-allow-origin
This field is required. Its value is either the value of the field at the time of the request Origin
, or the one *
that represents the request to accept any domain name.
(2) Access-control-allow-credentials
This field is optional. Its value is a Boolean value that indicates whether cookies are allowed to be sent. By default, cookies are not included in the Cors request. Set to true
, which means that the server expressly permits the cookie to be included in the request and sent to the server together. This value can only be set to true
if the server does not send cookies in the browser, delete the field.
(3) Access-control-expose-headers
This field is optional. When cors a request, XMLHttpRequest
the object's getResponseHeader()
method can only get 6 basic fields:,,,,, Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
. If you want to get the other fields, you must Access-Control-Expose-Headers
specify them inside. The example above specifies that the getResponseHeader('FooBar')
FooBar
value of the field can be returned.
3.2 Withcredentials Properties
As mentioned above, the Cors request does not send cookies and HTTP authentication information by default. If you want to send cookies to the server, on the one hand, the server agreed to specify the Access-Control-Allow-Credentials
field.
Access-Control-Allow-Credentials: true
On the other hand, the developer must open the attribute in the AJAX request withCredentials
.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;
Otherwise, the browser will not send even if the server agrees to send a cookie. Alternatively, the server requires a cookie to be set and the browser will not process it.
However, if the withCredentials
settings are omitted, some browsers will send cookies together. At this point, you can explicitly close withCredentials
.
xhr.withCredentials = false;
It is important to note that if you want to send a cookie, you Access-Control-Allow-Origin
cannot set it as an asterisk, and you must specify a domain name that is consistent with the requested Web page. At the same time, cookies still follow the same-origin policy, only the server domain name set up cookies will be uploaded, other domain name cookies will not upload, and (cross source) The original page code can document.cookie
not read the server domain name under the cookie.
Four, not simple request 4.1 pre-inspection request
Non-simple requests are those that have special requirements for the server, such as whether the request method is PUT
or DELETE
, or Content-Type
the type of the field application/json
.
A cors request that is not a simple request, adds an HTTP query request, called a "pre-test" request (preflight), before formal communication.
The browser asks the server first whether the domain name of the current page is on the server's license list, and which HTTP verb and header information fields you can use. The browser will issue a formal request only if you receive a positive reply, otherwise it will be an XMLHttpRequest
error.
The following is a browser JavaScript script.
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
In the code above, the HTTP request is a method PUT
that sends a custom header message X-Custom-Header
.
When the browser discovers that this is a simple request, it automatically issues a "prefetch" request, requiring the server to confirm that it can request it. The following is the HTTP header information for this "pre-check" request.
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
The request method for the "Pre-check" request is OPTIONS
to indicate that the request is for questioning. Header information, the key field is Origin
to indicate which source the request originated from.
In addition Origin
to fields, the header information for a "pre-test" request includes two special fields.
(1) Access-control-request-method
This field is required to list which HTTP methods are used by the browser's cors request, as in the example above PUT
.
(2) Access-control-request-headers
The field is a comma-delimited string that specifies the additional header information field that the browser cors request will send, as in the example above X-Custom-Header
.
4.2 Response to the pre-test request
After the server receives a "preflight" request, checks Origin
, Access-Control-Request-Method
and Access-Control-Request-Headers
fields, and confirms that a cross source request is allowed, you can respond.
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
In the HTTP response above, the key is the Access-Control-Allow-Origin
field, which indicates that the http://api.bob.com
data can be requested. The field can also be set to an asterisk to indicate that any cross source request is accepted.
Access-Control-Allow-Origin: *
If the browser denies the "prefetch" request, it returns a normal HTTP response, but there is no cors-related header information field. At this point, the browser will assume that the server does not agree with the pre-check request, thus triggering an error, XMLHttpRequest
captured by the object's onerror
callback function. The console prints the following error message.
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
Other Cors related fields that the server responds to are as follows.
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000
(1) Access-control-allow-methods
This field is required, and its value is a comma-delimited string indicating all the methods that the server supports for Cross-domain requests. Note that all supported methods are returned, not just the method that the browser requests. This is to avoid multiple "pre-test" requests.
(2) Access-control-allow-headers
If the browser request includes a Access-Control-Request-Headers
field, the Access-Control-Allow-Headers
field is required. It is also a comma-delimited string indicating that all header information fields supported by the server are not limited to the fields requested by the browser in the pre-test.
(3) Access-control-allow-credentials
The field has the same meaning as a simple request.
(4) Access-control-max-age
This field is optional to specify the validity period of this pre-check request, in seconds. In the above results, the validity period is 20 days (1.728 million seconds), that is, allow the cache to be cached for 1.728 million seconds (i.e. 20 days), during which no other pre-inspection request is issued.
4.3 The normal request and response of the browser
Once the server has passed the "pre-test" request, each time the browser's normal cors request, like a simple request, there will be a Origin
header information field. Server response, there will also be a Access-Control-Allow-Origin
header information field.
The following is a normal cors request for the browser after the "pre-check" request.
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
The fields of the above header information Origin
are automatically added by the browser.
Below is the server's normal response.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
In the header information above, the Access-Control-Allow-Origin
fields are necessarily included in each response.
V. Comparison with the JSONP
Cors and JSONP Use the same purpose, but more powerful than JSONP.
JSONP only supports GET
requests, Cors supports all types of HTTP requests. The advantage of JSONP is that it supports older browsers and can request data from Web sites that do not support cors.
Finish