How do the front and back ends communicate

  • Ajax
  • Websoket
  • CORS

Why does Ajax cross domain happen

Ajax cross-domain requests are not allowed because of the browser’s same-origin policy

Homology restriction

You cannot manipulate a document from another source without working with one

  • Development-time restrictions for browsers can be opened with the following command to allow cross-domain Windows
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Copy the code

Homologous purpose

  • Websites usually put some important information in cookies or LocalStorage. If there is no same-origin policy, this information can be shared. If someone steals website data maliciously, this information can be leaked. Therefore, the same origin policy is the foundation of browser security.

Cross-domain problems

  1. Cookie and localstorage cannot be obtained
  2. DOM doesn’t work
  3. The Ajax request could not be sent

homologous

Cognate indicates the protocol, domain name, and port

The composition of a domain name address

  • Generally we see the url does not show the port number, because the default port 80 is used, can be omitted
http:// (protocol) WWW (subdomain).abc.com(main domain) : 8080(port number)/somescript/jquery.jsCopy the code

Three tags that can cross domains

  1. Image:<img src='xxx'>: Used for statistics
  2. css: <link href='xxx'>: CDN resources can be used
  3. js: <script src='xxx'>: can be used for JSONP and CDN resources

Cross-domain solutions

JSONP

  • Principle: the use of script tag asynchronous loading to achieve

We pass the name of the callback to the server, send a request in the form of a loaded script tag, and the server returns a code block containing the code I passed with the name of the callback

  • The data returned by jSONp is not a JSON object but a JS script, which is a call to a function whose name is written at the time of the JSONP request. The jSONP request returns the value as a parameter.
  • The request type sent by JSONP is script

Json is ajax

not

Why is JSONP not Ajax

It is implemented using asynchronous loading of script tags

Do I need to change the background to use jSONP server

Yes, all cross-domain requests must be approved by the information provider

disadvantages

  • The server side needs to change. The return value is no longer a JSON object, but a JS script
  • The XHR request is not sent
  • Only GET requests are implemented and are vulnerable to XSS attacks

advantages

  • Compatibility is better, server transformation is very small

Native JS emulation

function jsonp({url,params,cb}) { return new Promise((resolve, reject) => { let script = document.createElement('script'); window[cb] = function (params) { resolve(params); } params = {... params,cb}; let arrs = []; for(let key in params){ arrs.push(`${key}=${params[key]}`); } script.src = `${url}? ${arrs.join('&')}`; document.body.appendChild(script); }); }; jsonp({ url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', params:{wd:'a'}, Cb :'show'}). Then (data=>{console.log('jsonp cross-domain request data :',data); });Copy the code

Jquery simulation

The jquery source code is also crossed by dynamically creating script tags

$.ajax({ url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', type: 'get', data: {wd:'a'}, dataType: Function (){}, error:function(){}});Copy the code

Vue: axios

this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', {
    params: {wd:'a'},
  jsonp: 'show'}).then((res) => {
    console.log(res); 
})
Copy the code

Hash

Scenario: The current page A has an iframe embedded in the cross-domain page

  1. A Operations on the page
var B = document.getElementByTagName('iframe')
B.src = B.src + '#' + 'data'
Copy the code
  1. B Data is received on the page
window.onhashchange = function(){
  let data = window.location.hash
}
Copy the code

postMessage

Scenario: Window A sends messages like window B across domains

  1. Send in A
Bwindon.postMessage('data','http://B.com')
Copy the code
  1. B accept
windoq.addEventListener('message',function(){
  console.log(event.origin)
  console.log(event.source)
  console.log(event.data)
},false)
Copy the code

WebSocket

var ws = new WebSocket('wss://echo.websocket.org') ws.onopen = function(evt){ console.log('Connection open... ') ws.send('Hello WebSockets') } ws.onmessage = function(evt){ console.log('Received Message'+ evt.data) } ws.onclose = function(evt){ console.log('Connection closed') }Copy the code

CORS The resources

Set the HTTP header on the server

response.setHeader('Access-Control-Allow-Origin','http://a.com,http://b.com') response.setHeader('Access-Control-Allow-Origin','X-Requested-With') Response. SetHeader (' Access - Control - Allow - Origin ', 'PUT, POST, GET, DELETE, OPTIONS') / / receiving cross-domain cookies response.setHeader('Access-Control-Allow-Credentials','true')Copy the code

There is no need to use pre-request to verify

Access-control-allow-methods: ‘PUT,DELETE

  1. GET
  2. HEAD
  3. POST

The content-type allowed in the response header

  1. Text/plain, text/HTML
  2. multipart/form-data
  3. application/x-www-form-urlencoded

Allow Headers. Everything else is handled by setting access-Control-allow-headers

  1. Accept
  2. Accept-Language
  3. Content-Language

Set the response header: any domain name/specified domain name can access the service

'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Origin': 'http://baidu.com'
Copy the code

CORS requests in advance

  1. Cross-domain request, set custom request headers
    fetch('http://localhost:8887', {
      method: 'POST',
      headers: {
        'X-Test-Cors': '123'
      }
    })
Copy the code
  1. Setting the response header
  response.writeHead(200, {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'X-Test-Cors',
    'Access-Control-Allow-Methods': 'PUT,DELELTE',
    'Access-Control-Max-Age':'1000'
  })
Copy the code

3. The browser sends a pre-request of type Options4. Then send the real request

  • By setting the response header access-Control-max-age, you can set how long a pre-request does not need to be repeated

Jsonp vs. CORS

1. Cors serves the same purpose as JSONP, but is more powerful than JSONP. Jsonp supports only GET requests, while CORS supports all types of HTTP requests. 3. Jsonp has the advantage of supporting older browsers and being able to request data from sites that do not support CORS.

Write an Ajax by hand, without relying on third-party libraries

  • Do not use the promise
var xhr =XMLHttpRequest ? new XMLHttpRequest() : New ActiveXObject() // To ensure cross-domain browser compatibility, Onreadystatechange = function (argument) {if(xhr.readyState === 4){if((xhr.status)  >200 && xhr.status <300)|| xhr.status === 304){ alert(xhr.responseTest) }else{ alert(xhr.status) } } Xhr. open('GET','/ API ',true)// Whether the request is made asynchronouslyCopy the code
  • The use of promise
function ajax(url) {
  const p = new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(JSON.parse(xhr.responseText))
        } else {
          reject(new Error('404 Not Found'))
        }
      }
    }
    xhr.send(null)
  })
  return p
}
ajax('/data/test.json')
  .then(res=>console.log(res))
  .catch(res=>console.error(err))
Copy the code