The same-origin Policy was first proposed by Netscape. The same-origin Policy requires the Same domain name, protocol, and port. Non-homologous scripts cannot access or manipulate page objects in other domains (such as DOM). As a well-known security policy, this policy is now used by all javascript-enabled browsers, although it is only a specification and not mandatory. As a result, this policy has become the core and most basic security function of the browser. Without the same origin policy, the security of the Web would be impossible.

Restrictions on the same-origin policy

In the web world of the same origin policy, domain barriers are built to ensure that each web page is independent of each other and cannot be directly accessed. Iframe and Ajax are restricted by it, while script tags are not.

Note: The following refers to ordinary cross-domain requests that are not CORS unless otherwise specified.

The iframe limit

  • Can access the same domain resources, read and write;
  • Read only when accessing cross-domain pages.

Ajax limit

Ajax is more restrictive than iframe.

  • Local resources can be read and written;
  • Cross-domain requests are blocked by the browser (Chrome does not initiate cross-domain requests. Other browsers generally send cross-domain requests, but the response is blocked by the browser).

Script limit

Script has no cross-domain restriction. This is because the files introduced by script tags cannot be obtained by the JS of the client, which does not affect the security of the original page. Therefore, the files introduced by Script tags do not need to follow the same origin policy of the browser. In contrast, ajax loads file content that can be retrieved by the client JS, and the imported file content may leak or affect the security of the original page. Therefore, Ajax must follow the same origin policy.

Pay attention to

The same origin policy requires the same domain, same protocol, and same port.

  • Co-domain means that host is the same, top-level domain name, level 1 domain name, level 2 domain name, and level 3 domain name must be the same, and the domain name cannot correspond to the IP address.
  • The HTTP and HTTPS protocols must be consistent.
  • Same port The port number must be the same.

With some exceptions, IE only validates the host name and access protocol, ignoring the port number.

There is a concept that needs to be clarified here. The so-called domain has nothing to do with the storage server of JS and other resources. For example, if you use script tag to request JS from Google.com, then the JS domain is Baidu.com. Instead of google.com. In other words, it can manipulate baidu.com page objects, but not Google.com page objects.

Cross domain access

In fact, we will inevitably need to make some cross-domain requests. Here are several ways to circumvent the same-origin policy:

Using the agent

Although Ajax and IFrame are restricted by the same origin policy, server-side code requests are not. We can forge a same origin request based on this to achieve cross-domain access. Here’s how to do it:

  1. Request web servers in the same domain;
  2. Web servers act as proxies to request real third-party servers;
  3. Once the agent takes the data, it returns it directly to the client with Ajax.

So we have cross-domain data.

JSONP

As a result, the script tag is not constrained by the same origin policy. Based on the Script tag, access in the form of JSONP can be made. Dynamic JS code can be generated by the third-party server to call back and forth the local JS method, and the parameters in the method are obtained by the third-party server in the background. Fill in the JS method as JSON. JSON with Padding.

1) Use JS to generate the following HTML code to do the JSONP request.

<script type="text/javascript" src="https://www.targetDomain.com/jsonp?callback=callbackName"></script>Copy the code

Using jquery, namely

jQuery.getJSON(
  "https://www.yourdomain.com/jsonp?callback=?".function(data) {
      console.log("name: "+ data.name); });Copy the code

Where callback function name “callback” is “?” That is, it does not need to be specified by the user, but is generated by jquery.

2) On the server side, taking Java as an example, see the following:

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// Get JSON data String jsonData = "{\"name\":\"jsonp\""}"; String callback = req.getParameter("callback"); String output = callback + "(" + jsonData + "); resp.setContentType("text/javascript"); PrintWriter out = resp.getWriter(); out.println(output); CallbackName ({\"name\":\"jsonp\""}); }Copy the code

postMessage

The new postMessage() method in ES5 allows scripts from different sources to communicate asynchronously in a limited manner, enabling cross-text file, multi-window, cross-domain messaging.

Grammar: postMessage (data, origin)

data: To pass data, the HTML5 specification states that this parameter can be any JavaScript primitive type or a copiable object. However, not all browsers can do this. Some browsers can only handle string arguments. So we recommend using the json.stringify () method to serialize object arguments when passing them, similar results can be achieved by referencing json2.js in earlier versions of IE.

Origin: String argument that specifies the source of the target window, protocol + host + port number [+URL]. The URL is ignored, so it can be omitted. For security reasons, the postMessage() method will only pass message to the specified window. This can be passed to any window, set to “/” if you want to specify the same origin as the current window.

The parent page sends a message:

window.frames[0].postMessage('message', origin)Copy the code

Iframe accepts messages:

window.addEventListener('message'.function(e){
    if(e.source! =window.parent) return;// Exit if the message source is not the parent page
      //TODO ...
});Copy the code

The e object has three important properties

  • Data represents the message passed from the parent page
  • Source, which represents the window object from which the message is sent
  • Origin: indicates the source (protocol + host + port number) that sends the message window.

CORS cross-domain access

HTML5 has brought a new way of cross-domain request — CORS, that is, cross-origin Resource Sharing. It is more secure than the aforementioned JSONP, postMessage, etc. The resource itself does not have the ability to guarantee itself against abuse. The goal of CORS is to protect resources from being accessed in the right way only by trusted access sources.

The protocol is supported by all major browsers and can be found at caniuse.com caniuse.com/#search=cor… .

In short, instead of just blocking cross-domain access, browsers examine the response header field of the destination site to determine whether to allow access to the current site. Typically, the server uses the following response header fields to notify the browser:

Response headers[edit]
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Expose-Headers
Access-Control-Max-AgeCopy the code

The solution to CORS is to add access information to the resource in the HTTP header field of the server’s Response. For example, station A only needs to add A field in response header to make station B cross-site access.

access-control-allow-origin:*Copy the code

Where * indicates wildcard, all domains can access this resource, if careful only station B is allowed to access:

access-control-allow-origin:<B-DOMAIN>Copy the code

This allows station B to access the resource directly, without the need for JSONP or iframe.

CORS requires METHOD access. For GET and POST requests, at least three methods should be specified as follows:

Access-Control-Allow-Methods: POST, GET, OPTIONSCopy the code

If it is a POST request and the submitted data type is JSON, CORS needs to specify headers.

Access-Control-Allow-Headers: Content-TypeCopy the code

CORS is cookie free by default. Setting the following fields will allow the browser to send cookies.

Access-Control-Allow-Credentials: trueCopy the code

In addition, in order to send authentication information such as cookies across sites, the Access-Control-Allow-Origin field will not be allowed to be set to * and will need to explicitly specify a domain name consistent with the requested web page.

At the same time, the request page must do the following explicit Settings to actually send cookies.

xhr.withCredentials = true;Copy the code

document.domain

By modifying the Domain property of the Document, we can communicate between domains and subdomains or between different subdomains (that is, they must be under the same level 1 domain name). The same-domain policy considers that the domain and subdomain belong to different domains, for example, a.com and Script.a.com are different domains. In this case, we cannot call the JavaScript method defined in Script.a.com in the page under a.com. But when we change their document domain property to a.com, the browser will assume that they are in the same domain, and we can retrieve each other’s data or manipulate each other’s DOM.

For example, we are at www.a.com/a.html and now want to get www.script.a.com/b.html, i.e. the primary domain is the same but the secondary domain is different. Here’s what you can do:

document.domain = 'a.com';
var iframe = document.createElement('iframe');
iframe.src = 'http://www.script.a.com/b.html';
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.addEventListener('load'.function(){
    // What TODO does when the load finishes
    //var _document = iframe.contentWindow.document;
     / /...
},false);Copy the code

Note:

  • Both pages should be set, even if the A.HTML page is already ina.comThe domain name must also be set explicitly.
  • Document.domain can only be set to a level 1 domain name, for example, page A cannot be set towww.a.com(Secondary domain name).

Using domain attributes across domains has the following limitations:

  • Two pages must be in the same level domain name, and must be the same protocol, the same port, that is, subdomain cross;
  • This parameter applies only to iframes.
The Same origin policy is bypassed in Internet Explorer. Procedure

Internet Explorer8 and earlier versions easily circumvent the same origin policy with document.domain, where domain properties can be easily exploited by overwriting document objects.

var document;
document = {};
document.domain = 'http://www.a.com';
console.log(document.domain);Copy the code

If you run this code in a recent browser, you may see a same-origin policy bypass error on the JavaScript console.

window.name

The name property of the window object is a special property. When the location of the window changes and the window is reloaded, its name property can remain the same. So we can use iframe on page A to load page B from other fields, and page B uses JavaScript to assign data to window.name. After loading the iframe (iframe.onload), page A changes the address of the iframe. Name = window.name = window.name = window.name = window.name = window.name = window.name = window.name = window.name = window.name = window.name = window.name = window.name Instead, use iframe to get its window.name). This approach is very suitable for one-way data requests, and the protocol is simple and secure. Do not execute external scripts without restrictions like JSONP does.

location.hash

Location. hash(between two iframes), also known as FIM, Fragment Identitier Messaging

Because the parent window can read and write the URL of the iframe, the iframe can also read and write the URL of the parent window. The part of the URL is called the hash, which is the hash and the character after the hash. It is used to locate the browser anchor point, and the Server doesn’t care about this part. So this part of the modification does not generate HTTP requests, but does generate browser history. The idea is to change the hash part of the URL for two-way communication. Each window sends a message by changing the location of the other window. (Since the two pages are not in the same domain, IE and Chrome do not allow you to change the value of parent-location. hash. So use a proxy iframe under the parent window domain name, and listen for changes in its OWN URL to receive messages. Some browsers do not support the onHashchange event and require polling to detect URL changes. Finally, there are drawbacks to this approach, such as data being directly exposed to the URL and limited data size and type.

Access Control

This cross-domain approach is currently supported in very few browsers that can send a cross-domain HTTP request (XMLHTTPRequest in Firefox, Google Chrome, etc., and XDomainRequest in IE8), The response to the request must contain an Access-Control-Allow-Origin HTTP response header that declares the accessibility of the request domain. For example, baidu.com sends a cross-domain HTTP request (via Ajax) to google.com’s getUsers.php, then getUsers.php must add the following response header:

header("Access-Control-Allow-Origin: http://www.baidu.com");// Indicates that Baidu.com is allowed to request this file across domainsCopy the code

flash URLLoder

Flash has its own set of security policies. The server can use the crossdomain. XML file to declare which domain SWF files can be accessed, and SWF can use the API to determine which domain SWF files can be loaded. When accessing resources across domains, such as requesting data from domain a.com on domain b.com, flash can be used to send HTTP requests.

  • First, change the crossdomain.xml on domain b.com (usually stored in the root directory, if not manually created) and add a.com to the whitelist.
<?xml version="1.0"? >
<cross-domain-policy>
<site-control permitted-cross-domain-policies="by-content-type"/>
<allow-access-from domain="a.com" />
</cross-domain-policy>Copy the code
  • Second, send HTTP request through Flash URLLoader, get the request and return;
  • Finally, the response results are passed to JavaScript through the Flash API.

Flash URLLoader is a common cross-domain solution, but it is not feasible if you need iOS support.

WebSocket

Before the emergence of WebSocket, in order to realize real-time push technology, many websites usually use Polling and Comet technology. Comet can be subdivided into two implementation methods, one is long Polling mechanism, the other is called streaming technology. These two methods are actually improvements on Polling technology. These schemes bring obvious disadvantages, requiring the browser to send HTTP requests to the server, which consumes a lot of server bandwidth and resources. Facing this situation, HTML5 defines the WebSocket protocol, which can better save server resources and bandwidth and realize real time push.

WebSocket is essentially a TCP-based protocol that aims to provide full-duplex, bidirectional communication over a single persistent link, giving browsers real-time communication capabilities in an event-based manner. Bidirectional communication means that both the server and client can send and respond to requests at the same time, rather than HTTP request and response.

In order to establish a WebSocket connection, the client browser first issues an HTTP request to the server. This request is different from the usual HTTP request and contains some additional header information, including “Upgrade: “WebSocket” indicates that this is an HTTP request for protocol upgrade. The server parses these additional headers and generates a reply message back to the client. The WebSocket connection between the client and the server is established, and the two sides can freely transfer information through this connection channel. And the connection persists until either the client or the server actively closes the connection.

A typical WebSocket client request header:

WebSocket Client request header


So much for this question. If you have any questions or good ideas, please leave a comment below.

Author: Louis

This paper links: louiszhai. Making. IO / 2016/03/02 /…

Refer to the article

  • Learn how to summarize the solution of front-end cross-domain request – JSONP- Ge Moji’s ITeye-ITeye technology website
  • Html5 postMessage addresses cross-domain, cross-window messaging -Samaritans- Blogpark
  • In-depth understanding of front-end cross-domain methods and principles – Kongjiea notes – blog channel -CSDN.NET
  • Basic principles of Cross-domain access and anti-theft chain -WEB front-end – Bole Online
  • Javascript cross-domain same-origin policy – KID
  • The same-origin policy explanation and the bypass (Part1) – FreeBuf.COM | attention hackers with a geek
  • Using Node. Js + Socket. IO build WebSocket real-time application | Pan Lianghu hakuouki zuisouroku
  • Several ways to access resources across domains