All browsers support this function. ie browsers cannot be lower than IE10. the entire CORS communication process is automatically completed by the browser without user participation. For developers, there is no difference in code between CORS communication and the same source AJAX communication. the browser will automatically add some additional header information once it finds that the AJAX request is cross-source, and sometimes there will be an additional request, but the user does not feel it. It allows the browser to send
XMLHttpRequest
To overcome the limitations that AJAX can only use the same source.
This article details the internal mechanism of CORS.
(Image Description: taken at Oasis Park in Al Ain, UAE)
I. Introduction
CORS must be supported by both browsers and servers. Currently, all browsers support this function. ie browsers cannot be lower than IE10.
The entire CORS communication process is completed automatically by the browser without the user's participation. For developers, CORS communication is no different from AJAX communication of the same source, and the code is exactly the same. Once the browser finds that AJAX requests are cross-origin, it will automatically add some additional header information, and sometimes there will be an additional request, but the user will not feel it.
Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, cross-source communication can be achieved.
2. Two types of requests
The browser divides CORS requests into two types: simple request and not-so-simple request ).
As long as the following two conditions are met, it is a simple request.
(1) The request method is one of the following three methods:
HEADGETPOST
(2) The HTTP header information does not exceed the following fields:
AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type: only three values are allowed.application/x-www-form-urlencoded
,multipart/form-data
,text/plain
Any request that does not satisfy both of the preceding conditions is a non-simple request.
The browser processes these two types of requests differently.
3. Basic Process of simple request 3.1
For simple requests, the browser directly sends a CORS request. Specifically, addOrigin
Field.
The following is an example. The browser finds that this cross-source AJAX request is a simple request and automatically addsOrigin
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,Origin
Indicates the source of the request (Protocol + domain name + port ). The server determines whether to accept the request based on this value.
IfOrigin
If the specified source is out of the permitted range, the server returns a normal HTTP response. The browser found that the response header does not containAccess-Control-Allow-Origin
Field (see the following section), you will know the error, and then throw an error.XMLHttpRequest
Ofonerror
Callback Function capture. Note: This error cannot be identified by the status code, because the HTTP response status code may be 200.
IfOrigin
When the specified domain name is within the permitted range, the response returned by the server will contain several additional 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
The header information above contains three CORS request-related fieldsAccess-Control-
.
(1) Access-Control-Allow-Origin
This field is required. The value is eitherOrigin
The field value is either*
To accept requests from any domain name.
(2) Access-Control-Allow-Credentials
This field is optional. Its value is a Boolean value that indicates whether Cookie sending is allowed. By default, cookies are not included in CORS requests. Settrue
The Cookie can be included in the request and sent to the server together. This value can only be settrue
If the server does not want the browser to send cookies, delete this field.
(3) Access-Control-Expose-Headers
This field is optional. When a CORS request is sent,XMLHttpRequest
ObjectgetResponseHeader()
The method can only get 6 basic fields:Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
. If you want to obtain other fields, you mustAccess-Control-Expose-Headers
. The example above specifies,getResponseHeader('FooBar')
Can ReturnFooBar
Field Value.
3.2 withCredentials attributes
As mentioned above, CORS requests do not send cookies and HTTP authentication information by default. If you want to send the Cookie to the server, on the one hand, the server must agree to specifyAccess-Control-Allow-Credentials
Field.
Access-Control-Allow-Credentials: true
On the other hand, developers must openwithCredentials
Attribute.
var xhr = new XMLHttpRequest();xhr.withCredentials = true;
Otherwise, the browser will not send the Cookie even if the server agrees to send it. Or, the browser does not process the Cookie.
However, ifwithCredentials
Some browsers send cookies together. In this case, you can explicitly disablewithCredentials
.
xhr.withCredentials = false;
Note that if you want to send a Cookie,Access-Control-Allow-Origin
You cannot set it as an asterisk. You must specify a domain name that is consistent with the requested webpage. At the same time, cookies still follow the same-origin policy. Only cookies set by the server domain name are uploaded. Cookies for other domain names are not uploaded.document.cookie
The Cookie under the server domain name cannot be read.
4. Non-simple request 4.1 Pre-check request
Non-simple requests are requests that have special requirements on the server. For example, the request method isPUT
OrDELETE
, OrContent-Type
The field type isapplication/json
.
For non-simple requests, an HTTP query request (preflight) is added before the formal communication ).
The browser first asks the server if the Domain Name of the current webpage is in the server's license list and what HTTP verb and header information fields can be used. The browser will send a formal response only when a positive response is received.XMLHttpRequest
Request. Otherwise, an error is returned.
The following is a JavaScript script of 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();
In the above Code, the HTTP request method isPUT
And send a custom header.X-Custom-Header
.
The browser finds that this is a non-simple request, and automatically sends a "pre-check" request, which requires the server to confirm. The following is the HTTP header of the "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 method used for the "pre-check" request isOPTIONS
Indicates that this request is used for inquiry. In the header, the keyword field isOrigin
Indicates the source from which the request comes from.
BesidesOrigin
Fields. The header information of the "pre-check" request includes two special fields.
(1) Access-Control-Request-Method
This field is required to list the HTTP methods used for browser CORS requests.PUT
.
(2) Access-Control-Request-Headers
This field is a comma-separated string that specifies the header information field that will be sent by the browser CORS request. In the preceding exampleX-Custom-Header
.
4.2 pre-check Request Response
After receiving the "pre-check" request, the server checksOrigin
,Access-Control-Request-Method
AndAccess-Control-Request-Headers
After the field, confirm that cross-source requests are allowed to 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 above HTTP response, the key isAccess-Control-Allow-Origin
Field, indicatinghttp://api.bob.com
Data can be requested. This field can also be set as an asterisk to allow any cross-Source request.
Access-Control-Allow-Origin: *
If the browser denies the "pre-check" request, a normal HTTP response is returned, but no CORS-related header information fields exist. In this case, the browser determines that the server does not agree with the pre-check request, so an error is triggered andXMLHttpRequest
Objectonerror
Callback Function capture. 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.
The server responds to the following CORS-related fields.
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. Its value is a comma-separated string that indicates all cross-origin request methods supported by the server. Note that all supported methods are returned, not just the method requested by the browser. This is to avoid multiple "pre-check" requests.
(2) Access-Control-Allow-Headers
If the browser request includesAccess-Control-Request-Headers
Field, thenAccess-Control-Allow-Headers
Fields are required. It is also a comma-separated string that indicates all header information fields supported by the server, not limited to the fields requested by the browser in "pre-check.
(3) Access-Control-Allow-Credentials
This field has the same meaning as a simple request.
(4) Access-Control-Max-Age
This field is optional and is used to specify the validity period of this pre-check request, in seconds. In the above results, the validity period is 20 days (1728000 seconds), that is, the 1728000 seconds (that is, 20 days) of the response can be cached. During this period, another pre-check request is not required.
4.3 normal browser requests and responses
Once the server passes the "pre-check" request, each normal CORS request in the browser will be the same as a simple request, there will beOrigin
Header information field. The response from the server also hasAccess-Control-Allow-Origin
Header information field.
The following is a normal CORS request from 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 header information aboveOrigin
Fields are automatically added by the browser.
The following is a normal response from the server.
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
In the header information above,Access-Control-Allow-Origin
Fields must be included in each response.
V. Comparison with JSONP
CORS is used for the same purpose as JSONP, but is more powerful than JSONP.
JSONP only supportsGET
Requests. CORS supports all types of HTTP requests. JSONP supports older browsers and requests for data from websites that do not support CORS.
(End)