preface
We do front-end, usually with the back-end docking interface that is a necessary thing, but many students may ignore a docking process may occur in the problem — cross-domain, that cross-domain is what? Why does it cross domains? How can it be solved?
Why cross domains?
Why do cross-domain problems occur? The browser’s same origin policy specifies that the protocol number, domain name, and port number must be the same
If there is a difference, there will be cross-domain problems, the consequences of not conforming to the same origin policy are
- 1.
LocalStorge, SessionStorge, and Cookie
The browser memory cannot be accessed across domains - 2,
DOM node
Unable to operate across domains - 3,
An Ajax request
Unable to request across domains
Note: An IP address can register multiple domain names, meaning that multiple domain names may refer to the same IP address, and even then, they do not comply with the same-origin policy
Cross-domain timing?
When does cross-domain happen?
- 1. The request was blocked by a cross-domain error from the browser as soon as it was sent (most answers)
- 2. The request is sent to the backend, which returns the data and is blocked by the browser’s cross-domain error when receiving the backend data
What kind is that? NPM I nodemon-g create an index.js and nodemon index create a node service
/ / index. Js http://127.0.0.1:8000
const http = require('http');
const port = 8000;
http.createServer(function (req, res) {
const { query } = urllib.parse(req.url, true);
console.log(query.name)
console.log('Back end')
res.end(JSON.stringify('Lin Three Hearts'));
}).listen(port, function () {
console.log('server is listening on port ' + port);
})
Copy the code
Create an index.html to write the front-end request code. Let’s write a simple AJAX request
http://127.0.0.1:5000/index.html / / index. The HTML
<script>
// Step 1: Create an asynchronous object
var ajax = new XMLHttpRequest();
// Step 2: Set the request URL parameters. Parameter 1 is the request type, parameter 2 is the request URL, can take parameters
ajax.open('get'.'http://127.0.0.1:8000? Name = Lin Sanxin from the front end);
// Step 3: Send the request
ajax.send();
// Step 4: Register the event onreadyStatechange to be called when the status changes
ajax.onreadystatechange = function(){
if(ajax.redayState == 4 && ajax.status == 200) {// Step 5: If you can enter this judgment, the data returned perfectly, and the requested page exists
console.log(ajax.responseText);// Enter the corresponding content
}
}
</script>
Copy the code
In the end, the front end did report a cross-domain error. However, this is not the result, and the key to finding the answer is to look at the backend node service where there is no output. So, answer 2 is correct
Codomain case && cross domain case?
If the protocol number – domain name – port number is the same, it is the same domain. Otherwise, it is cross-domain, which will lead to cross-domain error. Let us consolidate our understanding of the same-domain and cross-domain through a few examples.
Solutions across domains
In fact, cross-domain is a long time problem, there are many corresponding solutions, read on together!!
JSONP
As we said, is there anything that isn’t bound by cross-domain problems because of the same origin policy in browsers? In fact, there is, the following three tag load resource path is unfettered
- 1. Script tag:
<script SRC =" load resource path "></script>
- 2. Link tag:
<link herf=" load resource path "></link>
- 3. Img tag:
<img SRC =" load resource path "></img>
JSONP is able to get data from different domains by taking advantage of script’s unfettered SRC loading, but JSONP requires front-end and back-end cooperation to achieve the final cross-domain data acquisition. JSONP stands for: Script SRC to send a request, pass a method name callback to the back end, the back end takes the method name, concatenates the required data into a new string callback, and sends it to the front end, which receives the string. The method callback(required data) is automatically executed. Same old rule — diagram first, code second.
The back-end code
/ / index. Js http://127.0.0.1:8000
const http = require('http');
const urllib = require('url');
const port = 8000;
http.createServer(function(req,res){
const { query } = urllib.parse(req.url,true);
if(query && query.callback){
const { name, age, callback } = query
const person = `${name}This year,${age}Years old!!!!!! `
const str = `${callback}(The ${JSON.stringify(person)}) ` / / Mosaic callback (data)
res.end(str)
}else{
res.end(JSON.stringify('Nothing, you.'));
}
}).listen(port,function(){
console.log('server is listening on port ' + port);
})
Copy the code
The front-end code
http://127.0.0.1:5500/index.html / / index. The HTML
const jsonp = (url, params, cbName) = > {
return new Promise((resolve,reject) = > {
const script = document.createElement('script')
window[cbName] = (data) = > {
resolve(data)
document.body.removeChild(script) } params = { ... Params, callback: cbName}const str = Object.key(params).map(key= > `${key}=${params[key]}`)
script.src = `${url}?${arr.join('&')}`
document.body.appendChild(script)
})
}
jsonp.('http://127.0.0.1:8000', {name:'Lin Three Hearts'.age: 23),'callback',).then(data= > {
console.log(data) // Lin Sanxin is 23 years old!!
}
Copy the code
The downside of JSONP is that it requires front-and-back coordination and only supports get request methods
WebSocket
What is a WebSocket? In fact, I do not understand, but I will not copy the MDN data directly like others, because I believe that you can not understand the copy.
WebSocket is a protocol (the same as HTTP, it is a protocol) and it can carry out cross-domain communication, why does it support cross-domain communication?
I found an article here why WebSocket can cross domains? That’s a good point
The back-end code
Install NPM I WS first
/ / index. Js http://127.0.0.1:8000
const Websocket = require('ws');
const port = 8000;
const ws = new Websocket.Server({ port })
ws.on('connection'.(obj) = >{
obj.on('message'.(data) = >{
data = JSON.parse(data.toString())
const { name, age } = data
obj.send(`${name}This year,${age}Years old!!!!!! `)})})Copy the code
The front-end code
http://127.0.0.1:5500/index.html / / index. The HTML
function myWebsocket(url,params){
return new Promise((resolve,reject) = >{
const socket = new WebSocket(url)
socket.onopen = () = > {
socket.send(JSON.stringify(params))
}
socket.onmessage = (e) = > {
resolve(e.data)
}
})
}
myWebsocket('ws: / / 127.0.0.1:8000', {name:'Lin Three Hearts'.age:23 }).then(data= >) {console.log(data) // Lin Sanxin is 23 years old!!
}
Copy the code
The results are as follows
Cors
Cors, full name of Cross-origin Resource Sharing, means cross-domain Resource Sharing. Cors is generally started by the back end. Once started, the front end can access the back end across domains. Why can the front end request the back end across domains if the back end turns on Cors? My understanding is: When the front end accesses the back end across domains, the back end enables Cors and sends the Access-Control-allow-Origin: domain name field to the front end (actually, there is more than one domain name). The front end browser checks whether the access-Control-Allow-Origin domain name is the same as the previous one. Browsers will not implement cross-domain interception, thus solving the cross-domain problem.
The back-end code
/ / index. Js http://127.0.0.1:8000
const http = require('http');
const urllib = require('url');
const port = 8000;
http.createServer(function(req,res){
/ / open Cors
res.writeHead(200, {* Allow all domain names
'Access-Control-Allow-Origin': 'http://127.0.0.1.5500'.// Allow request methods across domains, or * allow all methods
"Access-Control-Allow-Methods": 'DELETE,PUT,POST,GET,OPIIONS'.// The allowed header type
'Access-Contorl-Allow-Headers': 'Content-Type'
})
const { query : { name, age } } = urllib.parse(req.url, true);
res.end(`${name}This year,${age}Age!! `);
}).listen(port,function(){
console.log('server is listening on port ' + port);
})
Copy the code
The front-end code
http://127.0.0.1:5500/index.html / / index. The HTML
// Step 1: Create an asynchronous object
var ajax = new XMLHttpRequest();
// Step 2: Set the request URL parameters. Parameter 1 is the request type, parameter 2 is the request URL, can take parameters
ajax.open('get'.'http://127.0.0.1:8000? Name = age=23');
// Step 3: Send the request
ajax.send();
// Step 4: Register the event onreadyStatechange to be called when the status changes
ajax.onreadystatechang = function(){
if(ajax.readyState == 4 && ajax.status == 200) {// Step 5 If the judgment can be reached, the data returned perfectly, and the requested page exists
console.log(ajax.responseText); }}Copy the code
Node interface proxy
Or return to the same origin policy, the same-origin policy it is just a strategy of the browser, it is not limit the backend, namely after the front – end will be the same-origin policy limitations, but after the end – after the end, will not be restricted, so you can through the Node interface agent, access has been set up Cors backend 1 first, then let the back-end 1 to access back-end 2 to get the data to the back-end 1, Back-end 1 then passes the data to the front-end
Back-end 2 code
/ / index. Js http://127.0.0.1:8000
const http = require('http');
const urllib = require('url');
const port = 8000;
http.createServer(function (req, res) {
console.log(888)
const { query: { name, age } } = urllib.parse(req.url, true);
res.end(`${name}This year,${age}Age!! `)
}).listen(port, function () {
console.log('server is listening on port ' + port);
})
Copy the code
Create an index2.js and nodmeon index2.js
Back-end 1 code
/ / index2. Js http://127.0.0.1:8888
const http = require('http');
const urllib = require('url');
const querystring = require('querystring');
const port = 8888;
http.createServer(function (req, res) {
/ / open Cors
res.writeHead(200, {
* Allow all domain names
'Access-Control-Allow-Origin': 'http://127.0.0.1:5500'.// Allow request methods across domains, or * allow all methods
"Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS".// The allowed header type
'Access-Control-Allow-Headers': 'Content-Type'
})
const { query } = urllib.parse(req.url, true);
const { methods = 'GET', headers } = req
const proxyReq = http.request({
host: '127.0.0.1'.port: '8000'.path: ` /?${querystring.stringify(query)}`,
methods,
headers
}, proxyRes= > {
proxyRes.on('data'.chunk= > {
console.log(chunk.toString())
res.end(chunk.toString())
})
}).end()
}).listen(port, function () {
console.log('server is listening on port ' + port);
})
Copy the code
The front-end code
http://127.0.0.1:5500 / / index. The HTML
// Step 1: Create an asynchronous object
var ajax = new XMLHttpRequest();
// Step 2: Set the url parameters of the request. Parameter 1 is the type of the request, and parameter 2 is the URL of the request. You can dynamically pass parameter starName to the server
ajax.open('get'.'http://127.0.0.1:8888? Name = age=23');
// Step 3: Send the request
ajax.send();
// Step 4: Register the event onreadyStatechange to be called when the status changes
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
// Step 5 If the judgment can be reached, the data returned perfectly, and the requested page exists
console.log(ajax.responseText);// Enter the corresponding content}}Copy the code
The results are as follows
Nginx
In fact, Nginx is the same as Node proxy, but Nginx does not require us to build an intermediate service
To downloadnginxNginx. conf in the nginx directory:
server{
listen 8888;
server_name 127.0. 01.;
location /{
proxy_pass 127.0. 01.:8000; }}Copy the code
Finally, start nginx on nginx -s reload
The back-end code
/ / index. Js http://127.0.0.1:8000
const http = require('http');
const urllib = require('url');
const port = 8000;
http.createState(function(req,res){
const { query:{ name, age } } = urllib.parse(req.url,true);
res.end(`${name}This year,${age}Age!! `);
})
Copy the code
The front-end code
http://127.0.0.1:5500 / / index. The HTML
// Step 1: Create an asynchronous object
var ajax = XMLHttpRequest();
// Step 2: Set the url parameters of the request. Parameter 1 is the type of the request, and parameter 2 is the URL of the request. You can dynamically pass parameter starName to the server
ajax.open('get'.'http://127.0.0.1:8888? Name = age=23');
// Step 3: Send the request
ajax.send();
// Step 4: Register the event onreadyStatechange to be called when the status changes
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
// Step 5 If the judgment can be reached, the data returned perfectly, and the requested page exists
console.log(ajax.responseText);// Enter the corresponding content}}Copy the code
The results are as follows
postMessage
Scene: Use the iframe tags embedded in the http://127.0.0.1:5500/index.html page http://127.0.0.1:5555/index.html pages Although this two pages in a page, but need to nested iframe label, There’s no way for these two pages to communicate with each other because they have different port numbers, so there’s a cross domain problem between them according to the same origin policy so what do you do? Using postMessage, the two pages can communicate
HTTP: / / 127.0.0.1:5500 / index. HTML
<body>
<iframe src="http://127.0.0.1:5555/index.html" id="frame"></iframe>
</body>
<script>
document.getElementById('frame').onload = function () {
this.contentWindow.postMessage({ name: 'Lin Three Hearts'.age: 23 }, 'http://127.0.0.1:5555')
window.onmessage = function (e) {
console.log(e.data) // Lin Sanxin is 23 years old!!}}</script>
Copy the code
/ / http://127.0.0.1:5555/index.html
<script>
window.onmessage = function (e) {
const { data: { name, age }, origin } = e
e.source.postMessage(`${name}This year,${age}Age!! `, origin)
}
</script>
Copy the code
document.domain && iframe
Scenario: communication between a.sanxin.com/index.html and b.sanxin.com/index.html In normal cases, the above two cannot communicate with each other because their domain names are different. What should I do then? In fact, they have one thing in common, that is, their secondary domain name is sanxin.com, which allows them to communicate through document.domain && iframe
Because this rookie does not have a server temporarily, so temporarily use local to simulate
/ / http://127.0.0.1:5500/index.html
<body>
<iframe src="http://127.0.0.1:5555/index.html" id="frame"></iframe>
</body>
<script>
document.domain = '127.0.0.1'
document.getElementById('frame').onload = function () {
console.log(this.contentWindow.data) // Lin Sanxin is 23 years old!!
}
</script>
Copy the code
/ / http://127.0.0.1:5555/index.html
<script>
// window.name=" Lin Sanxin is 23 years old!!"
document.domain = '127.0.0.1'
var data = 'Lin Sanxin is 23 years old!! ';
</script>
Copy the code