Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the cross-domain problem of web front end

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article, the editor introduces in detail "how to solve the cross-domain problem of web front-end". The content is detailed, the steps are clear, and the details are handled properly. I hope this article "how to solve the cross-domain problem of web front-end" can help you solve your doubts.

Why cross domains?

Why is there a cross-domain problem? Then we have to talk about the same origin policy of the browser, which stipulates that the protocol number, domain name and port number must all be the same to conform to the same origin policy.

If there is a difference, there will be cross-domain problems, and the consequences of non-compliance with the same origin policy are

1. LocalStorge, SessionStorge, Cookie and other browsers' memory cannot be accessed across domains.

2. DOM nodes cannot operate across domains

3. Ajax request cannot be made across domains.

Note: an IP can register multiple different domain names, that is, multiple domain names may point to the same IP. Even so, they do not conform to the same origin policy.

Cross-domain timing?

When does cross-domain occur? I have tested many students and got two kinds of answers.

1. As soon as the request is made, it is stopped by the browser's cross-domain error (most people answer)

2. The request is sent to the backend, and the backend returns data. When the browser receives the backend data, it is stopped by the browser's cross-domain error.

Which one is it? We can verify that we first npm i nodemon-g, then create an index.js, and then nodemon index a node service

/ / index.js http://127.0.0.1:8000const http = require ('http'); const port = 8000 th http.createServer (function (req, res) {const {query} = urllib.parse (req.url, true); console.log (query.name) console.log (' to the backend') res.end (JSON.stringify ('Lin Sanxin'));}) .clients (port, function () {console.log ('server is listening on port' + port)) })

Create another index.html to write the request code for the front end. Let's write a simple AJAX request.

/ / index.html http://127.0.0.1:5500/index.html / / step 1: create an asynchronous object var ajax = new XMLHttpRequest (); / / step 2: set the url parameter of the request. Parameter 1 is the type of request, parameter 2 is the url of the request, and you can take the parameter ajax.open ('get',' http://127.0.0.1:8000?name= frontend Lin Sanxin') / / step 3: send the request ajax.send () / / step 4: register the event onreadystatechange status change and call ajax.onreadystatechange = function () {if (ajax.readyState = = 4 & & ajax.status = = 200) {/ / step 5 if you can get to this judgment, the data has come back perfectly, and the requested page is console.log (ajax.responseText); / / enter the corresponding content}}

In the end, the front end did report a cross-domain error. But this is not the result, if we want to know which answer, the key is to see if there is any output from the back-end node service, it is clear at a glance. Therefore, answer 2 is right.

The same domain situation & & cross-domain situation?

The same origin policy was mentioned earlier. To satisfy that the protocol number, domain name and port number are all the same is the same domain, otherwise it is cross-domain, which will lead to cross-domain error. Here are a few examples to consolidate your understanding of co-domain and cross-domain.

A solution to cross-domain

Cross-domain is actually a long-standing problem, and there are many corresponding solutions, so let's read on!

JSONP

As we said earlier, there is a cross-domain problem due to the existence of the browser homology policy, so is there anything that is not bound by the cross-domain problem? As a matter of fact, there are. The following three tags load resource paths unfettered.

1. Script tag:

2. Link tag:

3. Img tag:

On the other hand, JSONP takes advantage of script's unfettered src loading, so that it can get data from different domains. However, JSONP needs the cooperation of front-end and back-end to achieve the final cross-domain data acquisition.

The popular point of JSONP is to use the src of script to send a request, pass a method name callback to the backend, get the method name at the back end, splice the required data into a new string callback (required data) through a string, and send it to the front end. After receiving this string, the front end will automatically execute the method callback (required data).

Back-end code

/ / index.js http://127.0.0.1:8000const 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} ${age} this year! `const str = `${callback} (${JSON.stringify (person)})` / / spell it into callback (data) res.end (str);} else {res.end (JSON.stringify ('nothing'));}}) .else (port, function () {console.log ('server is listening on port' + port);})

Front-end code

/ / index.html http://127.0.0.1:5500/index.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 arr = Object.keys (params) .map (key = > `${key} = ${params[ key]}`) script.src = `${url}? ${arr.join ('&')} `document.body.appendChild (script)})} jsonp ('http://127.0.0.1:8000', {name:' Lin Sanxin', age: 23} 'callback') .then (data = > {console.log (data) / / Lin Sanxin is 23 years old this year! })

The disadvantage of JSONP is that it requires front and rear cooperation and only supports get request methods.

WebSocket

I understand that WebSocket is a protocol (at the same level as http, both protocols), and it can communicate across domains.

Back-end code

Install npm i ws first

/ / index.js http://127.0.0.1:8000const Websocket = require ('ws'); const port = 8000 X 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} ${age} this year! `)})})

Front-end code

/ / index.html http://127.0.0.1:5500/index.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 Sanxin, age: 23}). Then (data = > {console.log (data) / / Lin Sanxin is 23 years old! }) Cors

Cors, whose full name is Cross-Origin Resource Sharing, means cross-domain resource sharing. Cors is generally enabled by the backend. Once enabled, the frontend can access the backend across domains.

Why can the backend request the backend across domains when Cors is enabled at the backend? My understanding is: the frontend accesses the backend across domains, and the backend opens Cors, and sends the Access-Control-Allow-Origin: domain name field to the frontend (actually more than one). If the frontend browser judges that the domain name of Access-Control-Allow-Origin is the same as the frontend domain name, the browser will not implement cross-domain blocking, thus solving the cross-domain problem.

Back-end code

/ / index.js http://127.0.0.1:8000const http = require ('http'); const urllib = require (' url'); const port = 8000 Http.createServer (function (req, res) {/ / enable Cors res.writeHead (200,{ / / set cross-domain domain names, or set * allow all domain names' Access-Control-Allow-Origin': 'http://127.0.0.1:5500', / / request method for cross-domain permission) You can also set * allow all methods "Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS", / / allowed header type 'Access-Control-Allow-Headers':' Content-Type'}) const {query: {name, age}} = urllib.parse (req.url, true) Res.end (`$ {name}) this year ${age} is old! ) (port, function () {console.log ('server is listening on port' + port);})

Front-end code

/ / index.html http://127.0.0.1:5500/index.html / / step 1: create an asynchronous object var ajax = new XMLHttpRequest (); / / step 2: set the url parameter of the request. Parameter 1 is the type of the request, and parameter 2 is the url of the request. You can take the parameter ajax.open ('get',' http://127.0.0.1:8000?name= Lin Sanxin & age=23') / / step 3: send the request ajax.send () / / step 4: register the event onreadystatechange status change and call ajax.onreadystatechange = function () {if (ajax.readyState = = 4 & & ajax.status = = 200) {/ / step 5. If you can get to this judgment, the data is back perfectly, and the requested page is console.log (ajax.responseText). / / enter the corresponding content}} Node interface proxy

Back to the same origin policy, the same origin policy is only a policy of the browser. It is not limited to the back end, that is, the front end-back end will be restricted by the same origin policy, but the back end-back end will not be restricted. So you can access the backend 1 with Cors set through the Node interface proxy, and then let the backend 1 visit the backend 2 to obtain data to the backend 1, and then transfer the data to the front end.

Backend 2 code

/ / index.js http://127.0.0.1:8000const 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} ${age} this year! (port, function () {console.log ('server is listening on port' + port);})

Create an index2.js and nodmeon index2.js

Backend 1 code

/ / index2.js http://127.0.0.1:8888const http = require ('http'); const urllib = require (' url'); const querystring = require ('querystring'); const port = 8888 Http.createServer (function (req, res) {/ / enable Cors res.writeHead (200,{ / / set cross-domain domain names, or set * allow all domain names' Access-Control-Allow-Origin': 'http://127.0.0.1:5500', / / request method for cross-domain permission) You can also set * allow all methods "Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS", / / 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 ()}) .console.log (port, function () {console.log ('server is listening on port' + port)) })

Front-end code

/ / index.html http://127.0.0.1:5500// step 1: create 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 the parameter starName to the server ajax.open ('get',' http://127.0.0.1:8888?name= Lin Sanxin & age=23') with parameters. / / step 3: send the request ajax.send () / / step 4: register the event onreadystatechange status change and call ajax.onreadystatechange = function () {if (ajax.readyState = = 4 & & ajax.status = = 200) {/ / step 5. If you can get to this judgment, the data is back perfectly, and the requested page is console.log (ajax.responseText). / / enter the corresponding content}} Nginx

In fact, Nginx is the same as Node interface proxy, except that Nginx does not need us to build an intermediate service ourselves.

Download nginx first, and then modify the nginx.conf in the nginx directory as follows:

Server {listen 8888; server_name 127.0.0.1; location / {proxy_pass 127.0.0.1 server_name 8000;}}

Finally, start nginx through the command line nginx-s reload

Back-end code

/ / index.js http://127.0.0.1:8000const http = require ('http'); const urllib = require (' url'); const port = 8000 × http.createServer (function (req, res) {const {query: {name, age}} = urllib.parse (req.url, true); res.end (`$ {name} ${age} this year! ) (port, function () {console.log ('server is listening on port' + port);})

Front-end code

/ / index.html http://127.0.0.1:5500// step 1: create 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 the parameter starName to the server ajax.open ('get',' http://127.0.0.1:8888?name= Lin Sanxin & age=23') with parameters. / / step 3: send the request ajax.send () / / step 4: register the event onreadystatechange status change and call ajax.onreadystatechange = function () {if (ajax.readyState = = 4 & & ajax.status = = 200) {/ / step 5. If you can get to this judgment, the data is back perfectly, and the requested page is console.log (ajax.responseText). / / enter the corresponding content}} postMessage

Scenario: a page with a http://127.0.0.1:5555/index.html embedded in the iframe tag is used in the http://127.0.0.1:5500/index.html page

Although the two pages exist on the same page, they need to be nested with iframe tags. There is no communication between the two pages because their port numbers are different. According to the same origin policy, there is a cross-domain problem between them.

What should I do then? Use postMessage to enable the two pages to communicate

/ / http:127.0.0.1:5500/index.html document.getElementById ('frame'). Onload = function () {this.contentWindow.postMessage ({name:' Lin Sanxin', age: 23}, 'http://127.0.0.1:5555') _ window.onmessage = function (e) {console.log (e.data) / / Lin Sanxin is 23 years old! }} / / http://127.0.0.1:5555/index.html _ window.onmessage = function (e) {const {data: {name, age}, origin} = e e.source.postMessage (`$ {name} this year ${age} years old! `, origin)} document.domain & & iframe

Scenario: communication between a.sanxin.com/index.html and b.sanxin.com/index.html

In fact, the above two cannot communicate under normal circumstances, because they have different domain names and belong to cross-domain communication.

What are we going to do? In fact, they have one thing in common, that is, their secondary domain names are all sanxin.com, which allows them to communicate through document.domain & & iframe.

After reading this, the article "how to solve the cross-domain problem at the front end of web" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it yourself to understand it. If you want to know more about related articles, welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report