JavaScript cross-domain delivery message Summary

Source: Internet
Author: User

Now, please do it with me: Enter www.yhd.com in your browser's address bar and tap enter. After the site content is loaded, press F12 to open the browser's debug window. When you switch to the sources page, you will find that the page of the store you are currently seeing is from several different domains:

Some readers may be surprised to find that they have tried to access resources in a non-current domain before writing their own web pages, but how can a store do that?

Of course, this is not a shop's unique skill, but only the use of a number of cross-domain access technology. In this article, we will introduce a cross-domain access technology cors (cross-origin Resource sharing).

Why do you use CORS

We often need to give the right reasons when we need to make a technical decision. In the case of cors, the fundamental reason for using it is to complete cross-domain access to resources, that is, how to bypass Same-origin Policy.

So what is Same-origin policy? Simply put, a Web site accessed in one browser cannot access data from another site, unless the two sites have the same origin, which means they have the same protocol, host address, and port. Once there is a difference in the three data, the resource will be considered to be derived from different origin and thus not allowed to be accessed.

But this restriction is really too restrictive: a large website often has a series of subdomains. Exchanging data between these domains is limited by the Same-origin policy. To circumvent this limitation, the industry proposes a number of ways to address the problem, such as changing document.domain properties, cross-document messaging, JSONP, and Cors. Each of these solutions has its strengths, so we need to choose between them according to the different requirements.

It can be said that the method of changing the Document.domain property is the most direct and fast method, and it is more common. By setting the Document.domain property of the scripts obtained from different domains to the same value, you can make the scripts interact with each other. For example, a webpage obtained from "http://blog.ambergarden.com" can change the owning domain of the record in its Document.domain property by executing the following script:

1 document.domain = ' ambergarden.com ';

Then the script will be able to access the data in the ambergarden.com.

This approach also has its own disadvantage, that is, software developers can not casually set the value of the Document.domain property, at least in some browsers.

Cross-document messages are done by sending a message to the window instance. When used, the software developer needs to send a message to the window instance by invoking a window's PostMessage () function. The OnMessage event inside the window instance is then triggered, which causes the message handler function of the event to be called. However, when a message is received, the message handler first needs to determine the legitimacy of the message source to avoid the malicious user to send the message to the illegal execution of code.

JSONP is to return data from another field by embedding a <script> tag in the document. For example, add one of the following <script> tags to the page:

1 <script src= "Http://blog.ambergarden.com/someData?callback=some_func"/>

The <script> tag sends a GET request to http://blog.ambergarden.com/someData. After the data is returned to the client, the Some_func () function is called. Of course, this approach has a significant disadvantage, which is that only get operations are supported.

As you have just seen, each of the methods listed above has its own shortcomings and limitations. Compared to these methods, Cors does not have much work to do, and there are not so many restrictions. Therefore, in this article, we will mainly explain the cors.

CORS Run the process

Now let's look at a simple example of cross-domain access through cors. Assuming Ambergarden.com wants to return some data from a public data platform public-data.com, in the page logic, it can send a data request to public-data.com through the following code:

1 function Retrievedata () {2     var request = new XMLHttpRequest (); 3     request.open (' GET ', ' http://public-data.com/ Somedata ', true); 4     request.onreadystatechange = handler;5     request.send (); 6}

After running this code, the browser sends the following request to the service:

1 get/somedata/http/1.12 host:public-data.com3 ... 4 REFERER:HTTP://AMBERGARDEN.COM/SOMEPAGE.HTML5 origin:http://ambergarden.com

A service that supports the Cors protocol may give the following response:

1 http/1.1 OK2 access-control-allow-origin:http://ambergarden.com3 content-type:application/xml4 ... 5 6 [Payload here]

Here is a notable response header: Access-control-allow-origin. The response header is used to record the domain in which the resource can be accessed. After receiving the service-side response, the browser will see if the response contains a access-control-allow-origin response header. If the response header exists, the browser parses the content indicated in the response header. If it contains the domain where the current page is located, then the browser will know that this is an allowed cross-domain access, thus no longer restricting user access to the data based on Same-origin policy.

From the whole process of accessing the data, the scripts that users use to access data across domains are actually not different from normal scripts that access data in the same domain. The difference, however, is that only one more access-control-allow-origin response is in the response header.

Isn't it simple? In fact, we're just showing the simplest simple request execution process. Cors, however, will result in three requests for cross-domain access: Simple request,preflighted request and requests with credential.

If a request does not contain any custom request headers, and the HTTP verb it uses is one of get,head or post, then it is a simple request. However, when using post as the requested verb, the content-type of the request needs to be one of Application/x-www-form-urlencoded,multipart/form-data or Text/plain.

If a request contains any custom request headers, or if the HTTP verb it uses is any verb other than get,head or post, then it is a preflighted request. If the content-type of a POST request is not one of Application/x-www-form-urlencoded,multipart/form-data or text/plain, then it is also preflighted Request.

In general, a cross-domain request does not contain the user credentials for the current page. Once a cross-domain request contains the user credentials for the current page, it belongs to the requests with credential.

We've seen how the browser handles simple request in the front. So let's take a look at how the preflight request is executed. The running process compared to simple request,preflight Request is slightly more complicated.

Assuming that we are writing some data to the public data platform public-data.com, we need to send a POST request:

1 function SendData () {2     var request = new XMLHttpRequest (), 3         payload = ...; 4     request.open (' POST ', ' Http://public-data.com/someData ', true); 5     Request.setrequestheader (' X-custom-header ', ' custom_header_value '); 6     request.onreadystatechange = handler;7     request.send (payload); 8 }

After the code is executed, the browser first makes the request as follows:

1 options/somedata/http/1.12 host:public-data.com3 ... 4 ORIGIN:HTTP://AMBERGARDEN.COM5 Access-control-request-method:post6 Access-control-request-headers: X-custom-header

As you can see, the first thing we send is not the POST request, but the option request. The request also identifies the request type and the custom HTTP Header contained in the request through Access-control-request-method and access-control-request-headers. In fact, it is equivalent to asking the server for access to resources: "Hello, I want to send you the data here, can you see?" ”。 Sending a request to probe before actually accessing the resource is also the reason for the request being called the preflight.

After the options request is seen on the server, it parses the contents of the request and returns a response to tell the browser whether to allow data to be sent to it:

1 http/1.1 OK2 access-control-allow-origin:http://ambergarden.com3 access-control-allow-methods:post, GET, OPTIONS4 access-control-allow-headers:x-custom_header5 access-control-max-age:17280006 ...

The browser parses the response and understands that it is allowed to send data to the server before it sends a true POST request to the server:

1 post/somedata/http/1.12 host:public-data.com3 x-custom-header:custom_header_value4 ... 5 6 [Payload here]

The server receives and processes the request:

1 http/1.1 OK2 access-control-allow-origin:http://ambergarden.com3 content-type:application/xml4 ... 5 6 [Payload here]

The last request requests with credential is similar to the first two requests. Just when sending the request, we need to include the user credentials in the request:

1 function Retrievedata () {2     var request = new XMLHttpRequest (); 3     request.open (' GET ', ' http://public-data.com/ Somedata ', true); 4     request.withcredentials = true;5     request.onreadystatechange = handler;6     request.send (); 7}

In response to the server, it will have an additional access-control-allow-credentials response header:

1 http/1.1 OK2 access-control-allow-origin:http://ambergarden.com3 content-type:application/xml4 ... 5 6 [Payload here]

Integration to CORS the support

As you can see from the example above, the client does not need to change any data access logic when using Cors to access the data. All of the work is done automatically between the server and the browser. So if you want to integrate cors support for a system, the work we need to do is focus on the server.

Of course, integration works really simple: Add a filter to your Web. XML (or take advantage of the existing filter) and first determine which cors request it is based on the incoming request. Once we know the type of the request, we can decide in which way to respond to the user. The logic here is relatively simple, so I won't go into it.

JavaScript cross-domain delivery message Summary

Related Article

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.