Cors detailed [Translate]

Source: Internet
Author: User
Tags http 200 set cookie

Introduced

Because of the same-origin strategy, we used to cross-domain requests using methods such as json-p (unsafe) or proxies (which set up proxies and maintenance cumbersome). The cross-origin resource sharing (Cross-origin Resource sharing) is a Web-based specification that is built on the XMLHttpRequest object, allowing developers to send cross-domain requests on the browser side like the same rules as the same-origin request.

The usage scenario for cors is simple. For example, a site bob.com wants to request data for alice.com, which is not allowed in traditional requests because of the same-origin policy. However, bob.com requests alice.com by Cors and adds a few special response headers to the alice.com response header to achieve the purpose of bob.com acquiring alice.com data.

As you can see above, to achieve cors, you need to co-ordinate the client and server. Fortunately, if you're a client developer, a lot of specifics are blocked for you. Well, next we'll explain how the client initiates cross-domain requests and how the server is set up to support Cors.

Initiate a CORS Request

This section explains how to use JavaScript to initiate a cross-domain request.

- Create XMLHttpRequest Object-

The browser supports cors scenarios, as follows:

. Chrome

. Firefox 3.5+

. Opera 12+

. Safari 4+

. Internet Explorer 8+

Browsers support cors scenarios, see http://caniuse.com/#search =cors

Both Chrome,firefox,opera and Safari use the XMLHttpRequest2 object. Internet Explorer uses similar object xdomainrequest, which works roughly the same as XMLHttpRequest, but adds additional security precautions.

Because of browser differences, first, you need to create a suitable request object based on the browser's difference. Nicholas Zakas wrote a simple helper method to block out browser differences, as follows:

functioncreatecorsrequest (method, url) {varXHR =NewXMLHttpRequest (); if("Withcredentials"inchxhr) {        //checks if the Xhlhttprequest object has a "withcredentials" property        //the "Withcredentials" property exists only in the XMLHttpReqeust2 objectXhr.open (method, URL,true); }Else if(typeofXdomainrequest! = "undefined"){        //Otherwise, check the Xdomainrequest        //xdomainrequest only exists in IE and through which cors requests are initiatedXHR =Newxdomainrequest ();    Xhr.open (method, URL); }Else{        //Otherwise, cors is not supported by the browserXHR =NULL; }    returnxhr;}varXHR = createcorsrequest (' GET ', URL);if(!xhr) {    Throw NewError (' CORS not supported '); }

- Event Handling-

The original XMLHttpRequest object has only one event handle:

onReadyStateChange, handles all responses. Although onReadyStateChange is still available, XMLHttpRequest2 introduces more new event handlers, as follows:

Event handle

Describe

onloadstart*

When a request is initiated

OnProgress

When data is loaded and sent

onabort*

When the request is interrupted. For example, calling the Abort () method

OnError

When the request fails

OnLoad

When the request is successful

OnTimeOut

When the request time exceeds the developer's set time

onloadend*

When the request is complete (success or failure)

Above, any event handle with an asterisk (*), IE's xdomainrequest is not supported.

Source: http://www.w3.org/TR/XMLHttpRequest2/#events

In most cases, we will use the OnLoad and OnError events at least:

function () {    var responsetext = xhr.responsetext;    Console.log (responsetext);     // Handling Responses  function() {    console.log (' There is an error! ' );}

When an error occurs in the request, the browser is not able to report the specific error very kindly. For example, Firefox will report 0 status and empty status text for all errors. The browser can also use the log to feed back error messages, but the information is not accessible by JavaScript. When handling the OnError event handle, you will know that there is an error and nothing else.

-withcredentials-

Standard Cors requests, by default, do not send or set cookie values. In order to include cookies when requested, we need to set XMLHttpRequest's Withcredentials property to True:

true;

In order for it to work, the server must also set Access-control-allow-credentials to true in the response header to turn on credentials. As follows:

true;

When the Withcredentials property is set, all cookies are brought with the remote domain request, and they are set. Note that these cookie values still follow the same-origin policy, so our JavaScript code still cannot get cookies from document.cookie or response headers, they are only controlled by the remote domain.

- Send Request-

Now that our Cors request is set up, we can initiate the request by calling the Send () method, as follows:

Xhr.send ();

If the request has a request body, it can be sent as a parameter in the Send method.

Client-side cors that's it! Assuming that the server is already set up cors, our onload event handle will be triggered when the server returns a response, just like the standard homologous XHR request you are familiar with.

- end-to-end example-

The following is a complete cors example. Run the sample and view the actual request operation in the browser debugger.

//creates a Xhr object.functioncreatecorsrequest (method, url) {varXHR =NewXMLHttpRequest (); if("Withcredentials"inchxhr) {    //XHR for Chrome/firefox/opera/safari.Xhr.open (method, URL,true); } Else if(typeofXdomainrequest! = "undefined") {    //xdomainrequest for IE.XHR =Newxdomainrequest ();  Xhr.open (method, URL); } Else {    //Cors is not supported.XHR =NULL; }  returnxhr;}//helper Functions: Parsing the title tag in the response contentfunctionGetTitle (text) {returnText.match (' <title> (. *)?</title> ') [1];}//initiate a cors request.functionmakecorsrequest () {//HTML5 Rocks supports CORS.  varurl = ' http://updates.html5rocks.com '; varXHR = createcorsrequest (' GET ', URL); if(!xhr) {Alert (' CORS not supported '); return; }  //response processing.Xhr.onload =function() {    varText =Xhr.responsetext; vartitle =getTitle (text); Alert (' Response from CORS request to ' + URL + ': ' +title);  }; Xhr.onerror=function() {alert (' Woops, there was an error making the request. ');  }; Xhr.send ();}
server-side configuration CORS

The most onerous processing for cors is between the browser and the server. When a browser sends a cors request, some additional response headers are added, and sometimes additional requests are sent. These additional steps are transparent to the client, but we can find them through a package parser, such as Wireshark.

Browser manufacturers are responsible for browser-side implementations. This section explains how the server can set its head to support Cors.

-cors Request Type-

There are two forms of cross-domain requests:

1. Simple Request

2, non-simple request

A simple request satisfies the following conditions:

. The HTTP request method (case-sensitive) is one of the following:

。 HEAD

。 GET

。 POST

. HTTP header matching (not distinguishing between uppercase and lowercase) is the following:

。 Accept

。 Accept-language

。 Content-language

。 Last-event-id

。 Content-type, but the assignment is only one of the following:

-application/x-www-form-urlencoded

-multipart/form-data

-text/plain

The characteristics of simple requests are as follows, because they do not need to use cors to initiate cross-domain requests in the browser. For example, Json-p initiates a GET request across domains, and HTML uses post to submit a form.

Any other request, as long as the above conditions are not met, is a non-trivial request, and when a non-simple request is initiated, additional communication (also called a pre-request) between the browser and the server is required. OK, let's go on a cross-domain tour together.

- process A simple request-

We start with a simple request from the client. The following code shows how to use JavaScript to initiate a simple request get, and the actual HTTP request made by the browser.

Javascript:

var url = ' http://api.alice.com/cors '; var xhr = createcorsrequest (' GET ', url); xhr.send ();

HTTP request:

Get/cors http/1.1origin:http://api.bob.comHost:api.alice.comAccept- language:en-usconnection:keep-aliveuser-agent:mozilla/5.0 ...

It is important to note that a valid Cors request always contains an Origin header, which is automatically added by the browser and cannot be manipulated by the user. Also, the value of this Origin header consists of a protocol (such as HTTP), a domain name (such as bob.com) and a port (including, for example, 81 if not the default port), such as http://api.alice.com.

However, it is also important to note that if a request contains an Origin header, it is not necessarily a cross-domain request. Although all cors requests will contain an Origin header, some homologous requests may also contain it. For example, Firefox does not include an Origin header when initiating a homologous request, but under Chrome and Safari, the origin header is included in the originating Post/put/delete request, except for originating a homologous get request that does not contain the origin header. For example, here is a homologous request containing Origin's head:

Post/cors http/1.1origin:http://api.bob.comHost:api.bob.com

The good news is that the browser does not expect the server to return a cors response header for the same-origin request. Therefore, regardless of whether there is a cors header, the response of the homologous request is sent directly to the user. However, if our server code returns an error, assuming the source information origin is not in the server request list, then include the request source in the head origin.

The following is a valid server response for Cors:

Access-control-allow-origin:http://api.bob.comtrue; Access-control-expose-headers:foobarcontent-type:text/html; Charset=utf-8

All cors-related headers start with "access-control-". More, see below:

Access-control-allow-origin (required)-the request header must be included in all valid cors response headers; otherwise, omitting the response header causes the Cors request to fail. The value is either the same as the value of origin for the request header (as in the example above), or it is set to an asterisk ' * ' to match any origin. If you want your data to be available to any site, use ' * '. However, if you want effective control, set the value to an actual value.

access-control-allow-credentials (optional)-by default, a cors request is sent, and cookies are not shipped. However, the use of the response header allows cookies to be included in the Cors request. Note that the response header only has a unique legal value of true (all lowercase). If you do not need a cookie value, do not include the response header, rather than setting the value of the response header to false. The response header access-control-allow-credentials needs to be used in conjunction with the Withcredentials property of the XMLHttpRequest2 object. Cookies can be included when both properties are set to true. For example, Withcredentials is set to true, but the response header does not contain a access-control-allow-credentials response header, and the request fails (and vice versa). When sending a cors request, it is best not to bring cookies unless you are sure you want to include cookies in your request.

access-control-expose-headers (optional)The-xmlhttprequest2 object has a getResponseHeader () method that returns a special response header value. In a cors request, the getResponseHeader () method can only get a simple response header, as follows:

. Cache-control

. Content-language

. Content-type

. Expires

. Last-modified

. Pragma

If you want the client to be able to get other header information, you must set the Access-control-expose-headers response header. The value of the response header can be the name of the response header, but it needs to be separated by commas so that the client can get it through the getResponseHeader method.

- handling a non-trivial request-

On top of that, we learned a simple request get, but what if we want to do something more? For example, we want to use a put or delete request, or we want to use Content-type:application/json to support JSON. So, we need to master the ' non-simple request ' that is described in this section.

When we use a non-trivial request, the client appears to be sending only one request, but in fact, to complete a non-trivial request, the client is privately requesting two requests from the server. The first request is to confirm the permissions to the server and, once authorized, to initiate a second request (a real data request). And, the first request can also be cached, so not every time we initiate a non-trivial request, it will be pre-requested.

For example, the non-simple request is as follows:

Javascript:

var url = ' http://api.alice.com/cors '; var xhr = createcorsrequest (' PUT ', url); Xhr.setrequestheader (' x-custom-header ', ' value '); Xhr.send ();

In the above code, the HTTP request method is put, and a custom header information X-custom-header is sent.

The browser discovers that this is a non-trivial request, and automatically issues a "preflight" request, requiring the server to confirm that it can request it. The following is the HTTP header information for this "preflight" 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 ...

As with simple requests, the browser automatically adds Origin header information to each request, including the pre-check request here. The method for pre-checking requests is options (so make sure our server responds to this method). And, it also contains two special header information, as follows:

Access-control-request-method: This field represents what the actual Cors is HTTP method, such as the Put method above, and the field is required, even if it is a simple request method (Get,post,head).

access-control-request-headers: This field is a comma-delimited string that specifies the header information fields that the browser cors request will send extra, such as the x-custom-header above.

As we have mentioned above, the purpose of the preflight request is to confirm the actual Cors request permissions to the server, so how does it check?

In fact, it is the validation of two special request headers (Access-control-request-method and access-control-request-headers) in the pre-check request. After the server receives a "preflight" request, after checking the origin, Access-control-request-method, and Access-control-request-headers fields, confirm that the cross-origin request is allowed, respond as follows:

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-8

Access-control-allow-origin-As with a simple request, the pre-check response must also contain the header, described in detail in the access-control-allow-origin of the simple request.

Access-control-allow-methods (MUST)--it is a comma-delimited string of values that are made up of HTTP methods, indicating all the methods supported by the server for cross-domain requests. Note that all supported methods are returned, not just the one requested by the browser. Because pre-check requests can be cached, this avoids multiple "preflight" requests.

access-control-allow-headers--This field is required if the browser request includes a access-control-request-headers field. 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 preflight because they can be cached.

access-control-allow-credentials (optional)-As with simple requests, see this field in the simple request above.

access-control-max-age (optional)-if a non-trivial cors request is initiated each time, it is too expensive to send two requests to the server, so the field can specify how many seconds the pre-check request can be cached.

Once the pre-check gets the authorization information, the browser sends a true cross-domain request. Also, requests and server responses are the same as simple cors requests.

Second request (actual cors request), as follows:

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 response is as follows:

Access-control-allow-origin:http://api.bob.comcontent-type:text/html; Charset=utf-8

If the server wants to reject the cors request, it can return a normal response (such as HTTP 200), which does not contain any header information that is part of Cors. If the pre-check request is not approved, that is, there is no response to the cors header, then the browser does not initiate a second actual request, as the following server responds to the pre-check request:

// Error-No cors header information, so indicates an invalid request content-type:text/html; Charset=utf-8

An error is triggered and captured by the onerror callback function of the XMLHttpRequest object. The console will print the following error message:

Original: Https://www.html5rocks.com/en/tutorials/cors/?redirect_from_locale=zh

Cors detailed [Translate]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.