define

Cross-domain refers to a document or script in one domain trying to request resources in another domain. Cross-domain is a broad term here. What we usually mean by cross-domain is narrowly defined, a class of request scenarios that are restricted by the browser’s same-origin policy. The same-origin policy, can reading nguyen other teacher, and speak very detailed: www.ruanyifeng.com/blog/2016/0…

In summary, due to browser security restrictions, data cannot be requested directly across domains, including different root domains, secondary domains, or different ports, unless the destination domain authorizes access. If you want to solve the same origin policy and implement transport, you need to cross domain. The website URL is composed of protocol + domain name + port + path, and may also contain query parameters and anchors. Here I borrowed the diagram drawn by Teacher Fang Yinghang:






1, the json

2. Cross-domain Resource Sharing (CORS)

3, postMessage

4, window.name + iframe

5. Location. hash + iframe

6、 document.domain + iframe

7. WebSocket protocol is cross-domain

8. Nginx proxies cross domains

1, the json

The principle of

Scripts can reference external links at will, despite the same origin policy restrictions. JSONP takes advantage of this feature to cross domains by creating a Script tag whose SRC points to a non-cognate URL.

methods

Create a jSONp (jsonp, jsonp, jsonp, jsonp, jsonp, jsonP, jsonP, jsonP); And remove the script tag

Native code implementation:

    function jsonp(url){
      return new Promise((resolve,reject) = >{
        let script = document.createElement('script')
        script.src = url
        document.body.appendChild(script)
        window.show = function(data){
          resolve(data)
          document.body.removeChild(script)
        }
      })
    } 
    jsonp(url).then((data) = >{
      console.log(data)
    })
Copy the code

However, JSONP also has obvious disadvantages. It can only send GET requests, and it is less secure and vulnerable to XSS attacks.

2. CORS(Cross-domain resource Sharing)

This method is also a more common one. The full name of CORS is cross-origin Resource Sharing, that is, cross-domain Resource Sharing. Generally speaking, if client A wants to send requests to server B of different domain names across domains, it should make an agreement with server B in advance, and then B’s back-end code will add A piece of code that allows A to send requests and respond to A to achieve the effect. The added back-end code is as follows :(express is used)

let express = require('express')
let app = express()
let whiteLists = ['// You agree to the requested page ']
app.use(function(req,res) = >{
    let origin =req.headers.origin
    if(whiteLists.includes(origin)){
        res.setHeader('Access-Control-Allow-Origin', origin)
    }
})

Copy the code

Res.setheader (‘ access-Control-allow-origin ‘, ‘// you agree to request and respond to the page domain name ‘) adds this line to indicate that the site is whitelisted and can respond to his request. Note that the default supported requests are GET, POST, and HEAD. If you want to use complex requests such as PUT, you also need the backend Setheader

res.setHeader('Access-Control-Allow-Methods'.'put')
Copy the code

Common setHeader summary:

res.setHeader('Access-Control-Allow-Origin',origin)
// Which address is allowed to send requests to me
res.SetHeader('Access-Control-Allow-Headers'.'name')
// Which header is allowed to access me
res.setHeader('Access-Control-Aloow-Methods'.'PUT')
// Which method is allowed to access me
res.setHeader('Access-Control-Allow-Credentials',ture)
// Cookies are allowed
res.setHeader('Access-COntrol-Max-Age'.1)
// Time allowed to live (unit: 5s)
res.setHeader('Access-Control-Expose-Headers'.'name')
// Allow return headers
Copy the code

3,postMessage

PostMessage is an HTML5 API that implements the window attribute for cross-domain operations. It solves the following problems:

  • Data transfer between a page and its newly opened window
  • Data transfer between multiple Windows
  • Page with nested IFrame message delivery

In general, postMessage() enables cross-text file, multi-window, cross-domain messaging.

Specific steps: 2. Set an onLoad event in the iframe tag to load. 3. OnMessage = function(e){console.log(e.data)} Continue to add e.ource. PostMessaqg (‘ content ‘, e.olin) to onMessage

The implementation code: http://localhost:8080/x.html page to http://localhost:8081/y.html ‘request’, then the latter back to the ‘response’.

x.html(http://localhost:8080/x.html)

  <iframe src="http://localhost:8081/y.html" frameborder="0" id="frame" onload="load()"></iframe>/ / it loads such as trigger an event / / embedded in http://localhost:8080/x.html<script>
      function load() {
        let frame = document.getElementById('frame')
        frame.contentWindow.postMessage('request'.'http://localhost:8081') // Send data
        window.onmessage = function(e) { // Accept the returned data
          console.log(e.data) //'response'}}</script>
Copy the code

y.html(http://localhost:8081/y.html)

  window.onmessage = function(e) {
    console.log(e.data) //'request'
    e.source.postMessage('response', e.origin)
 }
Copy the code

4,window.name

Window.name features: The name value persists after loading other pages and can be up to 2MB. We can use this feature to cross domains.

Implementation steps: Create an iframe tag with the SRC attribute set to the url from which the content is to be sent. 2. Set an onload event on the iframe. 4. Raise the onload event for the second time, read the data in the same domain window.name

Implementation code: x.html and Y.HTML in the same domain, send content to Z.html. Where, B.HTML is the middle proxy page, which is in the same domain as A.HTML, and the content is empty.

 <iframe src="http://localhost:8080/z.html" frameborder="0" id="iframe" onload="load()"></iframe>
 <script>
   let first = true
   function load(){
     if(first){
       let iframe = docuement.getElementById('iframe')       
       iframe.src = 'http://localhost:8080/y.html'
       fitst = false
       }else{
         console.log(iframe.contentWindow.name)
     }
     
   }
 </script>
Copy the code

5. Location. hash + iframe

X passes a hash value to Z. Z receives the hash value and passes the hash value to Y. Y puts the result into x’s hash. Xyz three pages, different fields use iframe location.hash to transfer values, the same fields directly js access to communicate.

Implementation code: X.html

  <iframe src="http://localhost.8081/z.html#text1" frameborder="0"></iframe>
 <script>
    window.onhashchange = function(){
      console.log(location.hash)
    } 
 </script>
Copy the code

z.html

<script> console.log(location.hash) let value - location.hash let iframe = document.createElement('iframe') iframe.src =  `http://localhost:8080/y.html#Ireceived${value}` document.body.appendChild(iframe) </script>Copy the code

y.html

  <script>
      window.parent.parent.location.hash = location.hash
  </script>
Copy the code

6, document.domain + iframe

Application scenario: Send requests from two web pages with the same secondary domain name, for example, a.test.com and b.test.com.

Document. domain =’test.com’; document.domain =’ same secondary domain ‘

Implementation code: A.HTML

 The a.html
 <iframe src="http://b.test.com:3000/b.html" frameborder="0" onload="load()" id="frame"></iframe>
 <script>
   document.domain = 'test.com'
   function load() {
     console.log(frame.contentWindow.a);
   }
 </script>
Copy the code

b.html

   The b.html
  <script>
    document.domain = 'test.com'
    let a = 100;
  </script>
Copy the code

So a can get the variable A of B

7, websocket

Websocket is an existing API. If you want to use Websocket, you can just use new

let socket = new Websocket()
Copy the code

However, this API is not compatible, so we usually use socket. IO that encapsulates zero webSocket

Here is the implementation code of the native Webocket:

<script> let socket = new WebSocket('ws://localhost:8080'); socket.onopen = function () { socket.send('request'); } socket.onMessage = function (e) {console.log(e.data); } </script>Copy the code

Server:

let express = require('express');
let app = express();
let WebSocket = require('ws');// Ws needs to be installed
let wss = new WebSocket.Server({port:8080});
wss.on('connection'.function(ws) {
  ws.on('message'.function (e) {
    console.log(e.data);
    ws.send('response')}); })Copy the code

8. Nginx proxies cross domains

Nginx is a lightweight Web server, reverse proxy server, we can build a Nginx server for forwarding, so as to achieve forwarding requests.

1. Configure a proxy server in nginx as a springboard. 2

Download nginx from nginx’s official website. Download nginx from nginx’s official website

The code to modify nignx.conf is as follows:

server { listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; # reverse proxy proxy_cookie_domain www.domain2.com www.domain1.com; # change cookie domain name index index.html index.htm; }}Copy the code