Author: Yeaseon Blog: YeaseonZhang.github. IO

Cross-domain problems are often involved in the development process, and there are many solutions to cross-domain problems. Next, we will sort out the common methods of front-end cross-domain.

The same-origin policy

What is cross-domain? Cross-domain is relative to homology. If the protocol, domain name, and port are the same, it is the same source. Browsers use the same origin policy to restrict documents or scripts loaded from one source from interacting with resources from another. This is a key security mechanism for isolating potentially malicious files, copied from MDN.

Common Solutions

document.domain

This scheme is mainly used in cross-domain situations where the primary domain is the same and the subdomains are different. For example, https://jdc.jd.com/ and https://www.jd.com/.

By opening a jdc.jd.com/ at www.jd.com/, where the JDC domain name is jdc.jd.com/, execute document.domain = ‘jd.com’ from the console; . Forcibly set the primary domain to realize the same origin.

var jdc = window.open('https://jdc.jd.com/');
// Execute after the JDC page is loaded
var divs = jdc.document.getElementsByTagName('div');

$(divs).css('border'.'1px solid red');Copy the code

The common practice is to load a cross-domain page resource through iframe. The window.open method is disabled in the browser as an advertisement.

domain.com/index.html

<iframe id="sub" src="http://sub.domain.com/index.html"></iframe>
<script>
  var username = 'yeseonzhang';
</script>Copy the code

sub.domain.com/index.html

<script>
  document.domain = 'domain.com';
  console.log(window.parent.username);
</script>Copy the code

location.hash

This cross-domain approach is implemented by setting/listening on the hash part of the URL, with the help of a third page.

The diagram above shows the inclusion relationship of the three pages and the hash passing process.

domain-a.com/a.html

<iframe id="iframe-b" src="http://domain-b.com/b.html"></iframe>
<script>
  var bPage = document.getElementById('iframe-b');

  /* step 1 */
  bPage.src = bPage.src + '#user=yeaseonzhang';

  function cb (res) {
    console.log(res);
  }
</script>Copy the code

domain-b.com/b.html

<iframe id="iframe-c" src="http://domain-a.com/c.html"></iframe>
<script>
  var cPage = document.getElementById('iframe-c');

  window.onhashchange = function () {
    /* step 2 */
    cPage.src = cPage.src + location.hash;
  }
</script>Copy the code

domain-a.com/c.html

<script>
  window.onhashchange = function () {
    /* step 3 */
     window.parent.parent.cb('success: ' + location.hash);
  }
</script>Copy the code

Since page A and page C are co-domain resources, page C can access page A resources through window.parent-parent.

window.name

This scheme is similar to location.hash, assisted by a third page. The window.name property is used to get/set the name of the window. Note that the window.name of the current window does not change with page reloads or jumps, so you can use this feature to redirect a cross-domain window.name to a same-domain page for reading.

domain-a.com/a.html

<script>
  var iframe = document.createElement('iframe');
  /* step 1 load the cross-domain page */
  iframe.src = 'http://domain-b.com/b.html';
  var domain = 'diff';

  /* Listen for iframe loading */
  iframe.onload = function () {
    if ('diff' == domain) {
      /* Step 2 redirects to the same-domain page */
      iframe.contentWindow.location = 'http://www.domain-a.com/c.html';
      domain = 'same';
    } else if ('same' == domain) {
      /* Get the window.name information for the local resource */
      cb(iframe.contentWindow.name);
      /* Clear data */
      iframe.contentWindow.name = ' '; }}function cb (res) {
    console.log(JSON.parse(res));
  }
</script>Copy the code

domain-b.com/b.html

<scirpt>*/ var obj = {username: 'yeaseonzhang'} window.name = json.stringify (obj);</script>Copy the code

domain-a.com/c.html

A domain C page can be an empty page that does not require any action.

JSONP

JSONP(JSON with Padding) is a way to use JSON. This allows the user to pass a callback argument to the server, which then wraps the JSON data as a function name when the server returns the data.

It is well known that all tags (,

The client

function todo(data){
  console.log('The author is: '+ data.name);
}

var script = document.createElement('script');
/* Callback argument, which specifies the name of the callback function. * /
script.src = 'http://www.yeaseonzhang.com/author?callback=todo';
document.body.appendChild(script);Copy the code

The service side

/* When the server receives the request, it returns the data in the argument of the callback function. */ todo({"name": "yeaseonzhang"});Copy the code

The todo() function is executed as a global function and is called as soon as the todo() function is defined.

postMessage

Window. postMessage is a secure, event-based messaging API in HTML5.

otherWindow.postMessage(message, targetOrigin, [transfer]);Copy the code

PostMessage (), the method takes three arguments:

  • message: Message content
  • targetOrigin: Indicates the source of the receiving message window, that is, protocol + domain name + port. It can also be set to a wildcard*, to all Windows
  • transfer: Optional argument (Boolean) that is passed along with messageTransferableObject. Ownership of these objects is transferred to the receiver of the message, and ownership is no longer retained by the sender.

Both sender and receiver can listen to each other’s messages through message events. The event object for the message event contains three properties:

  • event.source: a reference to the window object that sent the message, which can be used to establish two-way communication between the two Windows.
  • event.origin: INDICATES the URI that sends the message
  • event.data: Message content

Sender: domain-a.com/a.html

<script>
  var newWindow = window.open('http://domain-b.com/b.html');
  /* Send a message to b.html */
  newWindow.postMessage('Hello'.'http://domain-b.com/b.html');

  /* Two-way communication, receive reply messages from B.HTML */
  var onmessage = function (event) {
    var data = event.data;
    var origin = event.origin;
    var source = event.source;
    if (origin == 'http://domain-b.com/b.html') {
      console.log(data); //Nice to see you!}};window.addEventListener('message', onmessage, false);
</scirpt>Copy the code

Recipient: domain-b.com/b.html

<script>
  var onmessage = function (event) {
    var data = event.data;
    var origin = event.origin;
    var source = event.source;
    if (origin == 'http://domain-a.com/a.html') {
      console.log(data); //Hello
      /* Reply to a.html messages */
      source.postMessage('Nice to see you! '.'http://domain-a.com/a.html'); }};window.addEventListener('message', onmessage, false);
</script>Copy the code

WebSocket

WebSocket is a new protocol of HTML5, which implements full duplex communication between browser and server, as well as a cross-domain solution. For more information, please visit MDN.

/* The websocket protocol is WS/WSS, similar to HTTP/HTTPS */
wsUrl = 'WSS: / / 127.0.0.1:8090 / ws/';

/ * send * /
ws = new WebSocket(wsUrl);

/* Call */ when the connection is successfully established
ws.onopen = function (event) {
  console.log("websocket command onopen");
  var msg = {
    username: 'YeaseonZhang'
  }
  /* Send a message to the server using the send() method. The parameter must be a string */
  ws.send(JSON.stringify(msg));
};

*/ is called when the server sends a message to the client
ws.onmessage = function (event) {
  /* event.data contains messages sent by the server */
  console.log("websocket command onmessage: " + event.data);
  if (event.data === 'success') {
    /* Disconnect the websocket connection by close() */ws.close(); }};*/ is called when the connection is closed
ws.onclose = function (event) {
  console.log("websocket command onclose: " + event.data);
};

/* Call */ when an error occurs
ws.onerror = function (event) {
  console.log("websocket command onerror: " + event.data);
};Copy the code

The advantage of WebSocket is that it can not only achieve cross-domain, but also maintain long connections without polling to achieve real-time performance.

CORS

CORS is a W3C standard, which stands for “Cross-origin Resource Sharing”.

It just needs the support of the backend students, and the front end doesn’t need to do much extra work (besides carrying cookies).

As long as the server returns the header access-Control-allow-origin: domain-name, domain-name can also be set to *, the browser will Allow the cross-domain request.

conclusion

This is what I know about cross-domain solutions, and I hope it will help you.