In terms of cross-domain, this comes about because of the same origin policy
So what is the same origin policy? We say that when two addresses are different in protocol, domain name, or port number, we call them cross-domain.
Why not cross-domain support?
Cookie,localStorage does not support cross-domain
When a user logs in to a bank website, HTTP is stateless, they don’t know who’s logged in, they send you a cookie, they send you a sessionID that says it’s the current customer, assuming there’s no same-origin problem, and then the user visits a malicious site, and they send an Ajax request to the malicious site, and when they do that, The id given by the browser to the customer is given to the malicious website, and then the malicious website can take the ID given by the customer to visit the bank, which is equivalent to forging the user, which is not safe
The iframe DOM elements
In our page embedded in other people’s pages, we operate other pages in this page, the premise is that it must be the same domain, assuming that the user input account password login, my website can operate inside the page, then the user’s account password can be seen, it is not safe
Ajax does not support cross-domain interfaces that can be accessed by anyone who knows the link
With all these problems, why do we have to cross domains, often like front and back end separation?
The front end and back end are not on the same server address, the two want to communicate, how to communicate? You need some levers, some of them negotiated, some of them smart
- Disadvantages of JSOP XXS attack
- cors
- PostMessage communicates between two pages
- Window.name What does name do
- There are many location.hash sta frames
- Http-propxy Webpack has a proxy and middleware
- Nginx match
- Communication between Websocket pages, but no cross-domain issues
- Image ping and Comet
- Document. domain Indicates the second-level domain name and the first-level domain name, in the same domain, in the subdomain and in the parent domain
- Jsop shortcomings
The most typical is baidu search box
This is a standard JSONP interface, and it works by taking advantage of our ,script,img, etc import methods that are not subject to the source policy, Open the address https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=show show ({q: “b”, p: false, s: [” baidu “, “bt”, “btchina”, “be Yond “,” BBS “,” BBC “,”blog”,” Bobo combination “,” BB cream “]});
function show(data){
console.log(data)
}
show({q:"b".p:false.s: ["baidu"."bt"."btchina"."beyond"."bbs"."bbc"."blog"."Bobo combination"."Bb cream"]});
Copy the code
Is equivalent to
function show(data){
console.log(data)
}
/ / show ({p, q: "b", false, s: [" baidu ", "bt", "btchina", "beyond", "BBS", "the BBC", "blog", "bobo combination", "bb cream"]});
Copy the code
< script SRC = “https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=show” > < / script > / / this file domain implementation across domains
We’ve probably never written a global function, or said how to declare it, so how do we use it? We usually use third-party packages, or we can write our own
/ / <! --<script>-->
function jsonp({url,params,cb}){ //params:{wd:'a'} cb:'show'
return new Promise((resolve,reject) = > {
let script = document.createElement('script');
window[cb] = function(data){
resolve(data);
document.body.removeChild(script) } params = {... params,cb}// params = {wd:'a',cb:'show'}
let arr = [];
for(let key in params){
arr.push(`${key}=${params[key]}`);
} // arr[wd='a','cb='show']
script.src = `${url}?${arr.join('&')}`;// arr.join('&') = wd='a'&'cb='show'
document.body.appendChild(script); })}// JSONp will help us create callbacks and create script tags
jsonp({
url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su'.params: {wd:'a'},
cb:'show'
}).then(data= > {
console.log(data)
})
/ / show ({p, q: "b", false, s: [" baidu ", "bt", "btchina", "beyond", "BBS", "the BBC", "blog", "bobo combination", "bb cream"]});
//
/ / <! -- <script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&cb=show"></script> -->
Copy the code
Since we are using the method of importing script tags, we can only request the GET method, and imported script scripts can be vulnerable to malicious attacks (XSS), which is common but not recommended. H5 Please refer to www.runoob.com/json/json-j…
- cors
This has little to do with the front end, and is generally similar to the whitelist in the background, which only requires a few lines of code to be added
//res
let xhr = new XMLHttpRequest;
document.cookie = 'Name = Wow beauty';
xhr.withCredentials = true; // Cookies need to upload credentials across domains
xhr.open('PUT'.'http://localhost:4000/getData'.true);
xhr.setRequestHeader('name'.'zdl');
xhr.onreadystatechange = function(){
if(xhr.readyState === 4) {if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {console.log(xhr.response)
}
}
}
Copy the code
//res
let whitlist = ["http://localhost:3000"];
app.use(function(req,res,next){
let origin = req.hearders.origin;
if(whitlist.includs(origin)){
res.setHeader('Access-control-origin',origin);/ / source
res.setHeader('Access-control-Headers',name);/ / carry head
res.setHeader('Access-control-Method',put);/ / way
res.setHeader('Access-control-Credentials'.true);// Cookies can cross domains
res.setHeader('Access-control-Expose-Headers'.'name');// return the header}})Copy the code
- PostMessage communicates between two pages
In short, iframe communication
/ / is currently 3000 port a page http://localhost:3000/a.html
//<iframe src="http://localhost:4000/b.html" id = "frame" load()></iframe>
function load(){
let frame = document.getElementById('frame');
frame.contentWindow.postMessage('Am I beautiful?'.'http://localhost:4000/b.htm');
window.onmessage = function(e){
console.log(e.data)
}
}
Copy the code
/ / is currently 4000 port b page http://localhost:4000/b.html
//<iframe src="http://localhost:4000/b.html" id = "frame" load()></iframe>
window.onmessage= function(e){
console.log(e.data);
e.source.postMessage('You're beautiful', rigin)}Copy the code
- Window.name What does name do
- A and B are symtopic http://localhost:3000
- C is independent http://localhost:4000
- A obtains c’s data
- A refers to C first, and C puts the value in window.name and changes a’s reference address to B
/ / is currently 3000 port a page http://localhost:3000/a.html
//<iframe src="http://localhost:4000/c.html" id = "frame" onload = "load()"></iframe>
function load(){
let first = true;
if(first){// First load, c put name in
let iframe = document.getElementById('frame');
iframe.src = 'http://localhost:3000/b.html';// Change the reference address, load event
first = false;
frame.contentWindow.postMessage('Am I beautiful?'.'http://localhost:3000/b.htm');
window.onmessage = function(e){
console.log(e.data)
}
}else{// A and b are codomain
iframe.contentWindow.name // if a and b are in the same domain, they can be evaluated}}/ / c page
window.name = 'fsfa'
Copy the code
- There are many location.hash sta frames
The hash behind the path can also communicate
Purpose: A visits C
A passes the hash value to C, who can receive the hash value, but A can’t take the result of C, who passes it to B in the same way, and THEN B puts the result into the hash
//a page, so that C can take the hash value
//<iframe src="http://localhost:4000/c.html#fdhd" id = "frame" </iframe>
//c
console.log(location.hash);
let iframe = document.creatElement('iframe');
iframe.src = "http://localhost:3000/b.html#dsafaf";
document.body.apendChild(iframe);// Pass hach to b
//b, b and A are codomain, can pass
window.parent.parent.location.hash = location.hash
//a
window.onhashchange = function(){
console.log(location.hash)
}
Copy the code
Less use, also is to pass the iframe SRC transfer SRC = http://localhost:4000/c.html#dsfdf is only passed on the hash
-
Http-propxy Webpack has a proxy and middleware
-
Nginx configuration or command
-
Communication between websocket pages, but there is no cross-domain problem, can also achieve data transfer between
The advantage is fast transmission, equal transmission, different from Ajax is that the server can actively communicate with websocket, duplex, Ajax is duplex, please refer to Ruan Yifeng Websoke introduction, very detailed
// Advanced API is not compatible with socket. IO
let socket = new WebSocket('ws://localhost:3000');
// A successful link triggers the onOpen event
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
/ / open
/ / receive
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
/ / close
ws.onclose = function(evt) {
console.log("Connection closed.");
};
Copy the code
- document.domain
It solves some problems, but not all of them,
Domain name relationship: second-level domain name and first-level domain name
Locate the hosts configuration file configuration domain name:
127.0.0.1. A.a h.c n
127.0.0.1. B.a h.c n
Under the same domain, sub domain and the parent domain http://localhost:3000/a.html and http://localhost/two:3000/b.html
/ / a is http://a.ah.cn:3000/a.html
//<iframe src="http://b.ah.cn:3000/b.html" id = "frame" onload="load"></iframe>
document.domain = 'ah.cn';// Add domain to each solution
function load(){
console.log(frame.contentWindow.a)// Generally cross-domain
}
//b
document.domain = 'ah.cn';
var a = 100
Copy the code