The article answers the following questions:
- What is the same origin policy
- Why is the same-origin policy needed
- What is cross-domain
- Cross-domain approach 1: CORS
- Cross-domain approach 2: JSONP
The same-origin policy
What is the same origin policy
Originally, the same origin policy meant that A Cookie set by web page A could not be opened on web page B unless the two web pages were of the same origin. That’s what the browser does. By homology we mean “three of the same” :
- The agreement is the same
- Domain name is the same
- The same port
For example, 👇
http://www.example.com/dir2/other.html
homologoushttp://example.com/dir/other.html
: Different source (different domain name)http://v2.www.example.com/dir/other.html
: Different source (different domain name)http://www.example.com:81/dir/other.html
: Different source (different port)https://www.example.com/dir/page.html
: Different sources (different protocols)
The purpose of the same-origin policy
The purpose of the same origin policy is to ensure the security of user information and prevent malicious websites from stealing data.
Requests sent by different sites are almost identical (referers are different), but it’s not safe to separate referers only, so browsers have strict same-origin policies for user privacy.
limits
If not homologous, there are three behaviors that are restricted.
- Cookies, LocalStorage, and IndexedDB of non-cognate web pages cannot be read.
- DOM of non-homologous web pages cannot be accessed.
- You cannot send an AJAX request to a non-cognate address (you can, but the browser will reject the response).
The same origin policy restricts data access. We refer to CSS, JS, and images without actually knowing what they are. We are just referring to them.
So how do we cross domains when we’re faced with the need for different sites to access each other’s data? Answer: CORS and JSONP
What is cross-domain
Cross-domain is about getting rid of the same-origin policy and accessing data across sites
Cross-domain approach 1: CORS
The full name of CORS is “Cross-origin Resource Sharing”. It allows browsers to make XMLHttpRequest requests to servers across domains, overcoming the limitation that AJAX can only be used in the same source.
How to use
Allow access to a web site
response.setHeader('Access-Control-Allow-Origin'.'http://baodu.com') // Allow access to http://baodu.com
Copy the code
const request = new XMLHttpRequest()
request.open('get'.'http://qq.com:8888/friends.json') // Access data directly from other sites
request.onreadystatechange = () = > {
if (request.readyState === 4 && request.status === 200) {
console.log(request.response)
}
}
request.send()
// Successfully log, because qq.com:8888 has added access-Control-allow-origin
Copy the code
But IE does not support CORS, and some sites do not support CORS, so what to do? Using json
Cross-domain approach 2: JSONP
Example: If web site B wants to access web site A’s data, how can it be done with JSONP?
Step 1 (Site A) : Site A puts the data into A JS file
window['{{xxx}}']({{ data }})
Copy the code
Step 2 (website A) : Replace the data with A JS file
...}else if (path === '/friends.js') {
if (request.headers["referer"].indexOf("http://hack.com:9990") = = =0) { // The referer is not secure enough, so the random number is used
response.statusCode = 200
response.setHeader('Content-Type'.'text/javascript; charset=utf-8')
const string = fs.readFileSync('./public/friends.js').toString()
const data = fs.readFileSync('./public/friends.json').toString()
const string2 = string.replace('{{ data }}', data).replace('{{xxx}}', query.functionName)
response.write(string2)
response.end()
} else {
response.statusCode = 404The response. The end... ()}// When someone requests friends.js, send back the query.functionname containing the random number and the JSON data converted to the date string
Copy the code
Step 3 (site B) : Reference the JS file in site A
const random = 'hackJSONPCallBackName' + Math.random() // In order not to occupy any global variable, add a random number
// Get the data from the window
// This is actually a callback
window[random] = (data) = > {
console.log(data)
}
const script = document.createElement('script')
script.src = `http://qq.com:8888/friends.js?functionName=${random}` //
script.onload = () = > { // Delete the reference directly after the reference to prevent the body from getting too much content
script.remove()
}
document.body.appendChild(script) // Add to the body
Copy the code
At this point, website B gets the data of website A through Window
encapsulation
function jsonp(url) {
// Because it is asynchronous (requiring a call from the target site), we use promise here
return new Promise((resolve, reject) = > {
const random = 'hackJSONPCallBackName' + Math.random()
window[random] = (data) = > {
resolve(data)
}
const script = document.createElement('script')
script.src = `${url}? functionName=${random}` // I pass in a URL to get the data
script.onload = () = > {
script.remove()
}
script.onerror = () = > {
reject()
}
document.body.appendChild(script)
})
}
jsonp('http://qq.com:8888/friends.js')
.then((data) = > { // Give me a function after success to get data
console.log(data)
})
Copy the code
What is the json
JSONP is a cross-domain approach that we need to use when we cross domains, because the current browser, or for some other reason, cannot use CORS.
So we on his web site to create a script tag, and ask for another site js file, js file will contain some data, another site js files in your website to call a global function (this is a callback, pay attention to is the other web site calls, I just content) defines the function, the function contained in the data we want. The name of the callback can be a random number that we pass to the background as a callback, which will be returned to us and executed.
The json advantages
- Compatible with ie
- You can cross domain
JSON shortcomings
- Because it’s a script tag, you don’t know the status code, you don’t know the response header, you just know whether it succeeded or failed
- Because it is a script tag, it can only send get requests. Post is not supported