What is the Browser same-origin policy

The Same Origin policy is a convention. It is the core and most basic security function of a browser. If the Same Origin policy is absent, the normal functions of the browser may be affected. The Web is built on the same origin policy, and browsers are just an implementation of the same origin policy.

At its core, it believes that trusted content loaded from any site is not secure. When half-trusted scripts run in the sandbox by browsers, they should only be allowed to access resources from the same site, not potentially malicious resources from other sites.

The same domain name, protocol, and port are the same.

Relative to the homologous detection results of http://www.laixiangran.cn/home/index.html are listed in the table below:

In addition, the same origin policy is divided into the following two types:

  1. DOM same-origin policy: Operations on DOM of different source pages are prohibited. In this case, iframes of different domain names are restricted from accessing each other.
  2. XMLHttpRequest Same-origin policy: Disables the use of XHR objects to make HTTP requests to server addresses of different sources.

Why cross-domain restrictions

Cross-domain problems occur because of the browser same-origin policy. So why do browsers have cross-domain limitations? In fact, it is not hard to imagine that the main purpose of cross-domain restriction is for the user’s Internet security.

What security issues exist if browsers do not have same-origin policies. The following uses DOM same-origin policy and XMLHttpRequest same-origin policy as examples:

If there is no DOM same-origin policy, that is, iframes of different domains can access each other, then hackers can attack like this:

  1. Create a fake website that uses iframe to nest a bank websitehttp://mybank.com.
  2. Adjust the width and height of the iframe to the entire page, so that users come in just like the bank’s website, except for the domain name.
  3. At this point, if the user enters the account password, our main website can be accessed across domainshttp://mybank.comDom node, you can get the user account password.

Without the XMLHttpRequest same-origin policy, a hacker can carry out a CSRF (cross-site request forgery) attack:

  1. The user logs in to his bank pagehttp://mybank.com.http://mybank.comAdd the user id to the user’s cookie.
  2. Users browse malicious pageshttp://evil.comExecutes the malicious AJAX request code in the page.
  3. http://evil.comhttp://mybank.comWhen making an AJAX HTTP request, the request will default tohttp://mybank.comThe corresponding cookie is sent at the same time.
  4. The bank page extracts the user id from the cookie sent, verifies that the user is correct, and returns the request data in response. That’s when the data gets leaked.
  5. And because Ajax is executed in the background, the user is unaware of the process.

Therefore, with the same origin policy, we can be more secure online.

Cross-domain solutions

From the above we can see the function of the same origin policy of the browser. It is because of the cross domain restriction that we can safely surf the Internet. In practice, however, we sometimes need to overcome such limitations, so here are some cross-domain solutions.

CORS (Cross-domain Resource Sharing)

Cross-origin Resource Sharing (CORS) is a W3C standard that defines how browsers and servers should communicate when they must access cross-domain resources. The basic idea behind CORS is to use custom HTTP headers to let the browser communicate with the server to determine whether a request or response should succeed or fail.

CORS requires both browser and server support. Currently, all browsers support this function, and Internet Explorer cannot be lower than Internet Explorer 10.

The entire CORS communication process is completed automatically by the browser without user participation. For developers, CORS communication is no different from same-origin AJAX communication, and the code is exactly the same. As soon as the browser discovers that an AJAX request crosses the source, it automatically adds some additional headers, and sometimes an additional request, but the user doesn’t feel it.

Therefore, the key to CORS communication is the server. As long as the server implements the CORS interface, cross-source communication is possible.

Browsers classify CORS requests into two categories: 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 three:
  • HEAD
  • GET
  • POST
  1. HTTP headers do not exceed the following fields:
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-type: Application/X-www-form-urlencoded, multipart/form-data, text/plain

Any request that does not meet both conditions is a non-simple request.

Browsers treat these two requests differently.

A simple request

  1. An additional Origin header is appended to the request, which contains the source information (protocol, domain name, and port) of the requested page, so that the server can use this header information to decide whether or not to respond. Such as:Origin: http://www.laixiangran.cn
  2. If the server considers the request acceptable, it posts back the same source information in the Access-Control-Allow-Origin header (* if it is a public source). Such as:Access - Control - Allow - Origin: http://www.laixiangran.cn
  3. If there is no header or if there is a header but the source information does not match, the browser will reject the request. Normally, the browser handles the request. Note that neither the request nor the response contains cookie information.
  4. If cookie information needs to be included, the Ajax request needs to set the withCredentials attribute of XHR to true, and the server needs to set the response headerAccess-Control-Allow-Credentials: true.

Non-simple request

The browser sends a Preflight request to the server before sending the actual request. This request uses the OPTIONS method to send the following headers:

  • Origin: Same as a simple request.
  • Access-control-request-method: specifies the Method used by the Request itself.
  • Access-control-request-headers: (Optional) User-defined Headers. Multiple Headers are separated by commas (,).

Such as:

Origin: http://www.laixiangran.cn
Access-Control-Request-Method: POST
Access-Control-Request-Headers: NCZ
Copy the code

After sending this request, the server can decide whether to allow this type of request. The server communicates with the browser by sending the following header in the response:

  • Access-control-allow-origin: Same as a simple request.
  • Access-control-allow-methods: Specifies the allowed Methods. Multiple Methods are separated by commas.
  • Access-control-allow-headers: Allowed Headers, separated by commas.
  • Access-control-max-age: How long (in seconds) this Preflight request should be cached.

Such as:

Access-Control-Allow-Origin: http://www.laixiangran.cn
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: NCZ
Access-Control-Max-Age: 1728000
Copy the code

Once the server allows the request through a Preflight request, every subsequent normal BROWSER CORS request is treated as a simple request.

advantages

  • CORS communication is no different from same-origin AJAX communication, and the code is identical and easy to maintain.
  • All types of HTTP requests are supported.

disadvantages

  • Compatibility issues exist, especially for browsers below IE10.
  • The first time a non-simple request is sent, an additional request is made.

The json cross-domain

Because script tags are not affected by the browser’s same-origin policy, cross-domain references to resources are allowed. Therefore, you can create script tags dynamically and then cross domains using the SRC attribute, which is the basic principle behind JSONP cross domains.

The following example directly illustrates the process of implementing JSONP across domains:

// 1. Define a callback function handleResponse to receive the returned data
function handleResponse(data) {
    console.log(data);
};

// 2. Create a script tag dynamically and tell the back end that the callback is called handleResponse
var body = document.getElementsByTagName('body') [0];
var script = document.gerElement('script');
script.src = 'http://www.laixiangran.cn/json?callback=handleResponse';
body.appendChild(script);

/ / 3. Through the script. The SRC request ` http://www.laixiangran.cn/json?callback=handleResponse `,
// 4. The back end can recognize the URL format and process the request, then return handleResponse({"name": "laiXiangran "}) to the browser
// 5. The browser executes handleResponse({"name": "laiXiangran "}) as soon as it receives the handleResponse({"name":" LaiXiangran "}) method to retrieve the data returned by the back end, thus completing a cross-domain request.
Copy the code

advantages

  • Easy to use, no compatibility problems, one of the most popular cross-domain methods.

disadvantages

  • Only GET requests are supported.
  • Because it is executed from code loaded from another domain, it is likely that some malicious code will be embedded in the response if the other domain is not secure.
  • It is not easy to determine whether a JSONP request has failed. HTML5 adds an onError event handler to script tags, but there are compatibility issues.

Image Ping across domains

Because the IMG tag is not affected by the browser’s same origin policy, it allows cross-domain references to resources. Therefore, cross-domain can be carried out through the SRC attribute of the IMG tag, which is the basic principle of image Ping cross-domain.

Directly through the following example to illustrate the image Ping across the domain process:

var img = new Image();

// The onload and onError events tell you when the response was received, but you can't get the response text
img.onload = img.onerror = function() {
    console.log("Done!");
}

// Request data is sent as a query string
img.src = 'http://www.laixiangran.cn/test?name=laixiangran';
Copy the code

advantages

  • It has great advantages in tracking user click page or dynamic AD exposure times.

disadvantages

  • Only GET requests are supported.
  • Only one-way browser-to-server communication is possible because the browser does not have access to the server’s response text.

Server agent

Browsers have cross-domain restrictions, but servers do not have cross-domain problems, so the server can request resources from all domains and return them to the client.

The server proxy is versatile.

Document. The domain across domains

Document.domain can be used to cross domains in cases where the main domain name is the same but the subdomain is different. This approach is ideal for iframes that cross domains.

A page, for example, it is the address of the http://www.laixiangran.cn/a.html, there is an iframe in this page, it’s the SRC is http://laixiangran.cn/b.html. Obviously, the page is in a different domain from the iframe framework inside it, so there is no way to get the contents of the iframe by writing JS code in the page.

This is where document.domain comes in handy, As long as we put http://www.laixiangran.cn/a.html and http://laixiangran.cn/b.html these two page of the document. The domain are set to the same domain name. Document.domain can only be set to its own parent or higher, and the primary domain must be the same. Such as: The document.domain of a document in A.B.laixiangran. cn can be set to any of A.B.laixiangran. cn, B.laixiangran. cn, or laixiangran.cn. However, c.A.B.laixiangran. cn cannot be set to c.A.B.laixiangran. cn because it is the subdomain of the current domain and baidu.com because the main domain is different.

For example, set in the http://www.laixiangran.cn/a.html page document. The domain:

<iframe src="http://laixiangran.cn/b.html" id="myIframe" onload="test()">
<script>
    document.domain = 'laixiangran.cn'; // set to primary
    function test() {
        console.log(document.getElementById('myIframe').contentWindow);
    }
</script>
Copy the code

Also set up the document in the page http://laixiangran.cn/b.html. Domain, and it is also necessary, although this document is the domain of laixiangran. Cn, But you still have to explicitly set the document.domain value:

<script>
    document.domain = 'laixiangran.cn'; // document.domain is set to be the same as the main page
</script>
Copy the code

In this way, http://www.laixiangran.cn/a.html can be accessed through js to http://laixiangran.cn/b.html in various attributes and objects.

window.nameCross domain

The window object has a name attribute that has the following characteristics: That is, during the life cycle of a window, all pages loaded by the window (no matter pages of the same domain or pages of different domains) share the same window.name, and each page has read and write permissions to window.name. Window.name is persisted in all pages loaded by a window and is not reset for new pages.

The following example shows how to get data across domains using window.name.

Page http://www.laixiangran.cn/a.html code:

<iframe src="http://laixiangran.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    / / 2. The iframe load "after http://laixiangran.cn/b.html pages will perform this function
    function test() {
        var iframe = document.getElementById('myIframe');
        
        // reset iframe's onload event,
        // After resetting SRC,
        / / http://www.laixiangran.cn/a.html page with the iframe in the same source, you can visit each other
        iframe.onload = function() {
            var data = iframe.contentWindow.name; // 4. Get window.name in iframe
            console.log(data); // hello world!
        };
        
        / / 3. Reset a homologous with http://www.laixiangran.cn/a.html page page
        iframe.src = 'http://www.laixiangran.cn/c.html';
    }
</script>
Copy the code

Page http://laixiangran.cn/b.html code:

<script type="text/javascript">
    / / 1. For the current window. The name set an http://www.laixiangran.cn/a.html page to get the data values
    window.name = "hello world!";
</script>
Copy the code

The location. The hash across domains

The location.hash mode is cross-domain. The child frame changes the hash value of the parent frame SRC. The data is passed through this property and the page is not refreshed when the hash value is changed. But the number of bytes of data passed is finite.

Page http://www.laixiangran.cn/a.html code:

<iframe src="http://laixiangran.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    / / 2. The iframe load "after http://laixiangran.cn/b.html pages will perform this function
    function test() {
        / / 3. Access through http://laixiangran.cn/b.html page setup hash value
        var data = window.location.hash;
        console.log(data);
    }
</script>
Copy the code

Page http://laixiangran.cn/b.html code:

<script type="text/javascript">
    1. Set the hash value for the parent page
    parent.location.hash = "world";
</script>
Copy the code

PostMessage cross-domain

The window.postMessage(message, targetOrigin) method is a new feature introduced in HTML5 and can be used to send messages to other Window objects, regardless of whether the window object belongs to the same origin or a different source. This should be the future solution to dom cross-domain common method.

The window object from which the postMessage method is called is the window object from which the message is to be received. The first argument to this method, Message, is the message to be sent, and can only be a string. The second parameter, targetOrigin, is used to restrict the field of the window object that receives the message. If you do not want to restrict the field, you can use the wildcard *.

The Window object that needs to receive the message gets the incoming message by listening for its own Message event, the content of which is stored in the event object’s Data property.

Page http://www.laixiangran.cn/a.html code:

<iframe src="http://laixiangran.cn/b.html" id="myIframe" onload="test()" style="display: none;">
<script>
    / / 1. The iframe load "after http://laixiangran.cn/b.html pages will perform this function
    function test() {
        / / 2. http://laixiangran.cn/b.html pages for the window object,
        / / and then through the postMessage sends a message to the http://laixiangran.cn/b.html page
        var iframe = document.getElementById('myIframe');
        var win = iframe.contentWindow;
        win.postMessage('I'm from http://www.laixiangran.cn/a.html page news'.The '*');
    }
</script>
Copy the code

Page http://laixiangran.cn/b.html code:

<script type="text/javascript">
    // Register the message event to receive messages
    window.onmessage = function(e) {
        e = e || event; // Get the event object
        console.log(e.data); // Get the message sent via the data attribute
    }
</script>
Copy the code

The resources

  • Js several practical cross – domain method principle detailed explanation
  • All that cross-domain stuff
  • Cross-domain resource sharing (CORS

Please indicate the source of reprint, thank you!