First, understand the prerequisite for cross-domain: the browser’s same-origin policy.

What is origin? If two pages have the same protocol, host (the domain name is the same, but the secondary domain name and primary domain name are different), and port, the two pages are considered to be from the same origin.

JSONP principle and implementation

The same origin policy limits cross-domain requests, but more specifically, it only limits cross-domain read requests. There is no restriction on cross-domain embedding requests. For example, we can insert

JSONP is actually JSON + Padding, that is, it passes the JSON value to the Padding into a callback function, and the callback argument we get is the requested data.

let jsonp = function (url, data = {}, callback) {
  // Convert data to a URL string
  let dataStr = url.indexOf('? ') = = =- 1 ? '? ' : '&'
  for(let key in data) {
    dataStr += `${key}=${data[key]}& `
  }
  // Handle callback functions in the URL
  let cb_name = 'jsonpCallback'
  dataStr += 'callback=' + cb_name
  // Create the srcipt tag and add the SRC attribute value
  let scriptBody = document.createElement('script')
  scriptBody.src = url + dataStr
  // Mount the callback function on the global object
  window[cb_name] = function(data) {
    callback(data)
    document.body.removeChild(scriptBody)
  }
  // Append to the page to initiate the request immediately
  document.body.appendChild(scriptBody)
}
Copy the code

We can try it out on the console

You can see that we have successfully executed this request.

We can optimize it and rewrite it as a Promise

let jsonp = function (url, data = {}, callback='callback') {
  // Convert data to a URL string
  let dataStr = url.indexOf('? ') = = =- 1 ? '? ' : '&'
  for(let key in data) {
    dataStr += `${key}=${data[key]}& `
  }
  // Handle callback functions in the URL
  dataStr += 'callback=' + callback
  // Create the srcipt tag and add the SRC attribute value
  let scriptBody = document.createElement('script')
  scriptBody.src = url + dataStr
 
  // Append to the page to initiate the request immediately
  document.body.appendChild(scriptBody)
  // Return a promise
  return new Promise((resolve, reject) = > {
    window[callback] = (data) = > {
      try {
        resolve(data)
      } catch(e) {
        reject(e)
      } finally {
        // Remove the script element
        scriptBody.parentNode.removeChild(scriptBody)
        console.log(scriptBody)
      }
    }
  })
}
Copy the code

Let’s make one more request at the console

The characteristics of the json

  • Good compatibility
  • Only GET can be sent

CORS

Cross-origin Resource Sharing, in full, is a mechanism that uses HTTP request headers to tell browsers to allow a Web to make cross-domain Resource requests.

First, different requests are divided into two types by CORS: simple requests and non-simple requests

A simple request

Simple requests must meet the following conditions:

  • Use method:
    • GET
    • HEAD
    • POST
  • The manually set header fields are:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-type “Values must be in the following range”
      • applicatin/x-www-form-urlencoded
      • multipart/form-data
      • text/plain

When you send a simple request, the request header will have an Origin field, indicating the source. The response header will have an access-Control-Allow-Origin indicating the domain that can Access the resource, or if Origin is within that domain.

Note that sometimes we will set access-Control-allow-Origin to * to facilitate CORS, which means all fields will work, but if it is set to * we cannot carry cookies.

Non-simple request

If the simple request condition is not met, a non-simple request is sent. Before sending non-simple requests, an options request will be sent as a Preflight request, which will carry the following fields:

  • Access-control-request-method: POST tells the server that the actual Request will use the POST Method.
  • Access-control-request-headers: x-pingother, Content-Type tells the server which custom header fields are carried.

The general response header will contain:

  • Access-control-allow-origin Specifies the acceptable cross-domain request source
  • Access-control-allow-methods Acceptable cross-domain request Methods
  • Access-control-allow-headers Specifies the accepted custom request header field

The process of a non-simple request is as follows:

Other cross-domain solutions include Nginx proxy forwarding HTTP-proxy postMessage, etc.

More front-end knowledge related:

  • Front-end daily issues welcome to mention!
  • Front-end data structures and algorithms
  • Front end to understand the design pattern