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