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

Analysis of cross-domain problems in web front-end development

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article introduces the relevant knowledge of "analyzing cross-domain problems in web front-end development". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

What homologous strategy?

Same origin policy: the same origin policy (Same origin policy) is a convention, which is the core and basic security function of the browser. If the same origin policy is missing, the normal function of the browser may be affected. It can be said that Web is built on the basis of the same origin policy, and the browser is only an implementation of the same origin policy.

Homologous policy is a kind of convention, which is the core and basic security function of browsers. Without homologous policy, browsers are vulnerable to XSS, CSRF and other attacks. The so-called same origin means that the protocol, domain name and port are the same. Even if two different domain names point to the same ip address, they are not of the same origin.

Url component

After you understand the same origin policy, you also need to know the components of url by the way. Only after understanding url can you know what went wrong when there is cross-domain. Only in this way can you be against the backend, OPS and the air. O (∩ _ ∩) O ~

From the figure above, you can clearly see the meaning of each part of the url:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Protocol: the common protocol of the protocol is http

Auth: authentication, because the user name and password are transmitted in clear text, it is very insecure in non-HTTPS environment and is rarely used.

Hostname: host address, which can be either a domain name or an IP address

Port: Port http protocol default port is: Port 80, if not written, default is: Port 80

Pathname: the specified path of the network resource in the server

Serarch: query string if you need to query the content from the server, edit it here

Hash: hash pages may be divided into different segments. If you want to visit the page and go directly to the specified location, you can set it in this section.

Some caches are often used in the process of a project. When the browser caches for the security of the web page, the content of the cache is limited because of the same origin policy. In fact, it is also right to think about it. If you do not use the same origin policy, it's easy to flush out the cache.

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Cookie, LocalStorage, IndexDB, and so on cannot be read.

DOM is not available.

The AJAX request could not be sent.

Of course, browsers do not restrict everything, such as pictures, Internet resources, etc., or allow cross-domain requests. Tags are used to allow cross-domain requests, and only three tags allow cross-domain loading of resources:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

In the project development process, you will encounter the following errors from time to time, some people may not encounter in the development process, if so, you may encounter a very good backend or operation and maintenance.

XMLHttpRequest cannot load http://www.******.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

The above error report is a typical cross-domain error report. Since cross-domain is so common, what situations will lead to cross-domain problems:

Indicate whether to allow communication under the same domain name, allow different folders under the same domain name to allow the same domain name, different ports do not allow the same domain name, different protocols do not allow the domain name and ip corresponding to the domain name do not allow the same primary domain name, different sub-domain names do not allow the same domain name, different second-level domain names do not allow different domain names.

Cross-domain solution

Due to the limitations of browsers, there are a lot of cross-domain problems, and it is also for the sake of security. Since there must be some corresponding solutions for cross-domain, you can't stop working on the project after cross-domain. It may get cold in an instant. No more gossip.

JSONP

A word that is often mentioned when it comes to cross-domain is JSONP, saying JSONP all the time. But through what principle to achieve it? I think we should know what it is and then understand the principle of implementation.

What is JSONP?

A "usage mode" of JSONP:JSON that can be used to solve the problem of cross-domain data access in mainstream browsers. Because of the same origin policy, web pages located in server1.example.com generally cannot communicate with servers that are not server1.example.com, and the element of HTML is an exception. Using this open strategy of elements, web pages can get JSON data dynamically generated from other sources, and this usage pattern is called JSONP. The data captured with JSONP is not JSON, but arbitrary JavaScript, which is parsed with the JavaScript literal translator rather than the JSON parser. -selected from Baidu encyclopedia

Baidu gave a simple explanation for JSONP. After reading the whole paragraph, there are some small gains. The first script tag has an open strategy and can use the openness of src to solve its cross-domain problems. I would like to briefly state my personal point of view here. JSONP can be divided into two parts to interpret, JSON and padding,JSON, of course, do not need to explain, but a data format, padding in css is the meaning of inner filling, in fact, the principle of JSONP is similar to internal filling. By filling the data into the js file and then introducing it into the page, and using it in the page.

Have you ever noticed Baidu? in fact, Baidu's real-time search is achieved using JSONP. You can try it. If you search in Baidu, you will see a request that begins with sugrec in Network. This request is in the form of JSONP, and a segment connection is specially intercepted for your convenience.

Connection: https://www.baidu.com/sugrec?prod=pc&wd=json&pwd=json&cb=query return format: query ({"Q": "json", "p": false, "g": [{"type": "sug", "sa": "json 1", "Q": "json format"}, {"type": "sug") "sa": "json 2", "Q": "jsonp"}, {"type": "sug", "sa": "Song3", "Q": "json parsing"},...]})

Through the analysis of Baidu's real-time search, we can simply see the implementation principle of JSONP. The js file of the request contains a function whose name is that the parameters of the cb in the connection are transmitted to the background. The background processes and executes the function corresponding to the parameters. When the function is executed, the data will be passed to the corresponding function in the form of arguments to solve the cross-domain problem. Only code snippets are intercepted here for ease of reading.

Case study:

Front-end code:

('# btn') .click (function () {var frame = document.createElement ('script'); frame.src =' http://localhost:5000/jsonp?name=aaron&age=18&callback=query'; $('body') .append (frame); function query (res) {console.log (res.message+res.name+' you are' + res.age+'');}

Backend code:

Router.get ('/ jsonp', (req, res) = > {let {name,age,callback} = req.query; let data = {message:'success',name,age}; data = JSON.stringify (data); res.end (`${callback} (${data})`);})

Through the above code can be simple to achieve JSONP, although JSONP to solve the cross-domain problem, there are still many drawbacks, such as adding some script tags in the page, data can not be operated in both directions, and so on.

In particular, when using JSONP, be sure to put the inserted script under the applied function. This has something to do with the execution order of js. If you put the script tag on it, the method must report an error before it is read in the script tag, which is very important.

Document.domain

Document.domain projects are rarely used, and by default document.domain stores the hostname of the server where the document is loaded. You can output it in the console, and you will get the domain name segmentfault.com. What I use in the project is to combine the cross-domain encountered when iframe, and use the domain solution.

When using document.domain to achieve cross-domain, it should be noted that these two domain names must belong to the same first-level domain name! And the protocols and ports used must be consistent, otherwise you cannot use document.domain to cross-domain. Javascript forbids pages from two or more different domains to operate with each other for security reasons. On the other hand, pages in the same domain will not have any problems when they interact with each other.

Simply explain, for example, if you want to see the content in segmentfault.com in www.a.com and embed its web page into its web page using iframe, but at this time, the browser is not allowed to operate segmentfault.com directly through JavaScript, because the two pages belong to different domains. Before the operation, the browser will check whether it conforms to the same origin policy, if it conforms to the same origin policy, and vice versa.

If you want to cross-domain with document.domain, you must make it meet the same origin policy. In this case, you need to set the document.domain,document.domain to the same domain name. Note, however, that the setting of document.domain is limited, we can only set document.domain to our own or higher parent domain, and the primary domain must be the same.

For example:

A.com news.a.com

News.a.com belongs to a sub-domain of a.com, and the above rules have been met according to the above. If you want to achieve cross-domain operation, you need to operate on the document.domain of the sub-page.

Parent page:

Document.domain = 'a.compose; var ifr = document.createElement (' iframe'); ifr.src = 'news.a.com/map.html'; ifr.style.display =' none'; document.body.appendChild (ifr); ifr.onload = function () {var doc = ifr.contentDocument | | ifr.contentWindow.document; var oUl = doc.getElementById ('ul1'); alert (oUl[ XSS _ clean]); ifr.onload = null;}

Sub-pages:

Document.domain = 'a.compose; $ajax.get ({/ /... Omit})

The principle of its implementation is to load a page in the same domain as the target page you want to obtain data through ajax through iframe, so the page in this iframe can normally use ajax to get the data you want, and then through the method we just talked about modifying document.domain, so that we can fully control the iframe through js, so that we can let iframe send ajax requests. Then we can also get the data received.

Location.hash

If you understand the cross-domain principle of document.domain, then location.hash understands it very much. Like document.domain, the principle is to dynamically insert an iframe, and then point the src of the iframe to the server address, while the server also outputs a piece of JavaScript code, which also uses the communication between the sub-window to complete data transmission, and also has to deal with the same origin strategy.

Now that we have talked about what hash is exactly what is hash, let's talk about it alone. Although it is easy to understand, for new students, we may not know what hash is.

Hash: generally translated as hash, hash, or transliteration as hash, an input of arbitrary length (also known as pre-mapping pre-image) is transformed into a fixed-length output by a hash algorithm, which is a hash value. This transformation is a compressed mapping, that is, the space of the hash value is usually much smaller than the input space, and different inputs may be hashed into the same output, so it is not possible to determine the unique input value from the hash value. To put it simply, it is a function that compresses a message of any length into a message digest of a fixed length. -- excerpt from Baidu encyclopedia

After reading it, I feel that my whole person is not good, and I don't seem to understand it. The hash I understand refers to a process in which an input of any length is transformed into a fixed-length output through a hash algorithm, and the output is called a hash. This transformation is a compressed mapping, that is, the space occupied by the hash value is generally much smaller than that of the input value, and different inputs may hash out the same output (the probability is very small).

Hash has the following characteristics:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

If the two hash values are different (according to the same function), then the original input of the two hash values must be different.

If two hash values are the same, the two input values are likely to be the same (maximum probability), but they may also be different, which is called "hash collision".

Tamper resistance: for a data block, even if only one bit is changed, the hash value will change greatly.

It is an one-way function that is "asymmetric", that is, it is an irreversible mapping from plaintext to ciphertext, with only encryption process and no decryption process.

So what is the use of hash in normal project development? What can I do with hash? The most frequently used hash for the front end may be anchor positioning. Navigate to the element location specified by the trace point through different hash values.

Red black yellow pink

I won't dwell on more details here. If you want to know more, you can google yourself. If you go on, you may stray from the subject.

This paper briefly introduces the use of hash and hash, so how to use hash to achieve cross-domain? In fact, it is very simple, if the index page wants to get the data from the remote server, dynamically insert an iframe and point the src attribute of the iframe to the server address. At this time, the top window and the child window wrapping the iframe cannot communicate directly due to the same origin policy, so change the path of the child window and add the data to the path as the hash value of the changed path, and then you can communicate and add the data to the hash value of the index page address. The index page listens for changes in the hash value of the address and then makes a judgment and processes the data.

Parent page:

Since the change of the hash value will not change the URL of the web page, the server can parse the parameters in the url by getting the hash and return the data to the front end. Change the hash value through parent.location.hash, and then you can get the data of the child page like document.domain. Parent.location.hash this approach is limited and is not supported in IE and Chrome. So how should the whole problem be solved?

Add a file * .html (* represents any name) under the domain name of the same domain, then introduce * .html into the parent page through iframe, and add the interface iframe to request in * .html, which can be solved.

Http://localhost:6000/a.html

No function sendRequest () {var ifr = document.createElement ('iframe'); ifr.style.display =' none'; ifr.src = 'http://localhost:7000/b.html#Aaron'; document.body.appendChild (ifr);} function checkHash () {var data = location.hash?location.hash.substring (1):'; if (data) location.hash ='';} setInterval (checkHash,1000) _ window.onload = sendRequest

Http://localhost:7000/b.html

No function checkHash () {var data =''; switch (location.hash) {case'# Aaron': data ='my Aaron'; break; case'# Angie': data ='my Angie'; break; default: break;} data & & callBack ('#'+ data) } function callBack (hash) {var proxy = document.createElement ('iframe'); proxy.style.display =' none'; proxy.src = 'http://localhost/c.html'+hash; document.body.appendChild (proxy);} _ window.onload = checkHash

Http://localhost:6000/c.html

No parent.parent.location.hash = self.location.hash.substring (1)

There is a hidden iframe in the a.html, which points to the b.html of the foreign http://localhost:7000/b.html, and passes the hash value to b.html`b.html to get the hash value, generates the data value, and then dynamically creates the iframe. The iframe passes the data value to the c.html in the same domain as the a.html, because the hash and a.html` are in the same domain, so the cross-domain problem can be solved.

Window.name

Window.name is not a simple global attribute as long as it is under a window, no matter how the url changes, as long as the window.name is set, then it will not change all the time. Similarly, in iframe, even if the url is changing, the window.name in the iframe is a fixed value. Using this, we can achieve cross-domain.

Http://localhost:6000/a.html

Var ifr = document.querySelector ('iframe') ifr.style.display =' none' var flag = 0; ifr.onload = function () {if (flag = = 1) {ifr.contentWindow.close ();} else if (flag = = 0) {flag = 1; ifr.content_Window.location = 'http://localhost:6000/proxy.html';}}

Http://localhost:7000/b.html

Var person = {name: 'Aaron', age: 18} window.name = JSON.stringify (person)

Http://localhost:6000/proxy.html

Proxy

This is the proxy page.

There is an a.html under http://localhost:6000 and a b.html under http://localhost:7000. It creates an iframe tag in http://localhost:6000/a.html and points the address to http://localhost:7000/b.html. The window.name assignment in b.html saves a piece of data, but it cannot be obtained yet, because it is cross-domain, so We can set src to the http://localhost:6000/proxy.html of the current domain, although the domain name has changed, but the window.name has not changed. So we can get the data we want.

PostMessage (HTML5)

Many people may not know the whole API of postMessage. The new postMessage method in HTML5 allows scripts from different sources to communicate in an asynchronous manner, and can achieve cross-text file, multi-window, and cross-domain message delivery. PostMessage has been well supported in many browsers, so you can rest assured to use it. This method can listen to the content of sending cross-document messages by binding the message event of window.

The postMessage () method accepts two parameters

1. Data: the data to be passed. It is mentioned in the html5 specification that this parameter can be any basic type of JavaScript or a replicable object. However, not all browsers can do this. Some browsers can only handle string parameters, so we need to use the JSON.stringify () method to serialize object parameters when passing parameters. Referencing json2.js in a lower version of IE can achieve a similar effect.

1. Origin: string parameter, indicating the source of the target window, protocol + host + port number + URL,URL will be ignored, so it can not be written. This parameter is for security reasons. The postMessage () method only passes message to the specified window. Of course, you can also set the parameter to "*" if you want, so it can be passed to any window. If you want to specify the same origin as the current window, set it to "/".

Http://localhost:6000/a.html

No message sent _ window.onload = function () {var receiver = document.getElementById ('receiver'). ContentWindow; var btn = document.getElementById (' send'); btn.addEventListener ('click', function (e) {e.preventDefault (); var val = document.getElementById (' text'). Value; receiver.postMessage ("Hello" + val+ "!" , "http://localhost:7000");});}

Http://localhost:7000/b.html

No Hello World! _ window.onload = function () {var messageEle = document.getElementById ('message'); window.addEventListener (' message', function (e) {if (e.origin!) = "http://localhost:6000") {return;} messageelle [XSS _ clean] =" received message from "+ e.origin +": "+ e.data" });}

In this way we can receive messages from any window. For security, we use the MessageEvent object at this time to determine the message source, the MessageEvent object, which contains a lot of things.

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Data: as the name implies, it is the passed message

Source: the window object that sends the message

Origin: the source of the message window (protocol + host + port number)

The postMessage method is easier to use than the above methods, and there is no need to have too many tedious operations. It can be said that postMessage is a better solution for solving cross-domain problems. It does not appear particularly bloated code, and various browsers have good support.

Cross-domain resource sharing (CORS)

CORS: full name "cross-domain resource sharing" (Cross-origin resource sharing). CORS requires both the browser and the server to support cross-domain requests. At present, almost all browsers support CORS,IE, but not less than IE10. The whole process of CORS is completed automatically by the browser, and there is no need to make any settings at the front end, which is no different from sending ajax requests. The key of CORS lies in the server. As long as the server implements the CORS interface, it can realize cross-domain communication.

Cross-domain resource sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to allow Web applications running on an origin (domain) to access specified resources from different source servers. When a resource requests a resource from a different domain, protocol, or port than the server on which the resource itself resides, the resource initiates a cross-domain HTTP request. As mentioned above, src is not subject to the same origin policy, but for security reasons, browsers restrict cross-source HTTP requests made from within scripts. For example, XMLHttpRequest and FetchAPI follow the same origin policy. This means that Web applications using these API can only request HTTP resources from the same domain where the application is loaded, unless the response message contains the correct CORS response header.

All CORS-related headers are prefixed with Access-Control. Here are some details of each head.

Field description Access-Control-Allow-Methods this field is required, and its value is a comma-separated string indicating all cross-domain request methods supported by the server. Note that all supported methods are returned, not just the one requested by the browser. This is to avoid multiple "pre-check" requests for Access-Control-Allow-Headers. If the browser request includes an Access-Control-Request-Headers field, the Access-Control-Allow-Headers field is required. It is also a comma-separated string indicating that all header information fields supported by the server are not limited to the fields requested by the browser in "pre-check" Access-Control-Allow-Credentials this field has the same meaning as a simple request. Access-Control-Max-Age this field is optional, which is used to specify the validity period of this pre-inspection request (in seconds). In the above result, the validity period is 20 days (1728000 seconds), which allows the response to be cached for 1728000 seconds (that is, 20 days), during which there is no need to issue another pre-check request. Import express from "express"; import cors from "cors" Const app = express () const var corsOptions = {origin: 'http://example.com', optionsSuccessStatus: 200} app.get (' / products/:id', cors (corsOptions), (req, res, next) = > {res.json ({msg: 'This is CORS-enabled for only example.com.'})} app.listen (80, function () {console.log (' enable corba, port: 80')})

Using CORS to make a simple request is very easy, and no configuration is required for the front end, just like sending a normal ajax request. The only thing to note is that when you need to carry cookie information, you need to set withCredentials to true. The configuration of CORS is set entirely in the backend, and it is relatively easy to configure. At present, the compatibility for most browsers is also good. Now the most common application is CORS to solve cross-domain solutions.

WebSocket protocol cross-domain

WebSocket is a new API of HTML5, which can realize instant communication between client and server through WebSocket, such as chat room, synchronous rendering of service data and so on. WebSocket is peer-to-peer communication, and the server and the client can be done through some kind of identity. WebSocket is not restricted by the same origin policy, so you can use this feature to communicate directly with the server.

The following example does not use HTML5's WebSocket but uses socket.io to perform similar functions.

If you say a word: in fact, I always thought that WebSocket and Ajax are limited by the same homologous strategy. After learning, I found that it was not. I really learn that I am never too old (Guan Gu accent). O (∩ _ ∩) O

Server:

Var io = require ('socket.io') (1234); io.sockets.on (' connection', (client) = > {client.on ('message', function (msg) {/ / listen information processing client.send (' server received message:'+ msg);}); client.on ("disconnect", function () {/ / disconnect processing console.log ("client has disconnected") );}); console.log ("listen 1234...")

Client:

$(function () {var ioiosocket = io.connect ('http://localhost:1234/'); var $ul = $("ul"); var $input = $("input"); iosocket.on (' connect', function () {/ / connected processing $ul.append ($('connected') Iosocket.on ('message', function (message) {/ / receive information processing $ul.append ($('') .text (message)); iosocket.on ('disconnect', function () {/ / disconnect processing $ul.append (' Disconnected');});}) $input.keypress (function (event) {if (event.which = = 13) {/ / enter event.preventDefault (); console.log ("send:" + $input.val ()); iosocket.send ($input.val ()); $input.val ('');});})

Since Websocket supports cross-domain approach, that is to say, a Websocket service open to the public network can be accessed by anyone, which will make the data very insecure, so you can authenticate the connected domain name.

Server reverse generation

First of all, we learned what reverse generation is. In computer networks, reverse proxy is a kind of proxy server. According to the request of the client, the server obtains resources from one or more of its associated back-end servers (such as Web servers), and then returns these resources to the client. The client only knows the IP address of the reverse proxy, but does not know the existence of the server cluster behind the proxy server. -- excerpt from Baidu encyclopedia

Reverse proxy server: forwards the http request to another server or servers for nginx. This makes it easy to achieve cross-domain access. For example, N servers are deployed in the server, and when the client initiates a request, it does not need to directly request services on the N nodes in the server, but only needs to visit our proxy server. The proxy server is distributed to different server nodes according to the request content. This is only a usage scenario, of course, you can also do load balancing and so on.

Reverse agency is not particularly difficult to understand. The most common example in daily life is that when we dial manual customer service, we do not directly dial a phone number of customer service, but dial the switchboard number. When we dial, it will be handled by the switchboard and then distributed to different customer service personnel. R however, when the service staff needs to ask you to hang up and wait for a call back, it is not directly dialed to your phone, but also through the switchboard and then forwarded to your phone. In fact, this switchboard is equivalent to a reverse server. Although this example is not appropriate, it is more or less what it means.

Because I don't know much about Nginx, I don't know how to deal with this part, but I just have a simple understanding of reverse proxy, and I will fill in the relevant code when I learn Nginx later.

Nodejs agent cross-domain

In my opinion, using Nodejs for cross-domain is to use Node service to do an intermediate proxy forwarding, the principle is similar to reverse proxy, when accessing a URL, it needs to be distributed to another server URL address through the server. There is not too much repetition here, just look at the code.

The sample code goes below:

Main.js

Import http from "http"; import httpProxy from "http-proxy"; / / create a new proxy ProxyServer object const proxy = httpProxy.createProxyServer ({}); / / catch exception proxy.on ('error', function (err, req, res) {res.writeHead (500, {' Content-Type': 'text/plain'}); res.end (' error');}) / / in each request, call the proxy.web (req, res config) method to request distribution const server = http.createServer ((req, res) = > {/ / here you can customize your routing distribution let host = req.headers.host, ip = req.headers ['xmuri distribution for] | req.connection.remoteAddress Switch (host) {case 'www.a.com': proxy.web (req, res, {target:' http://localhost:3000'}); break; case 'www.b.com': proxy.web (req, res, {target:' http://localhost:4000'}); break Default: res.writeHead (200,{ 'Content-Type':' text/plain'}); res.end ('Hello Aaronghouse') ;}}); server.listen (8080)

As shown in the code, when accessing www.a.com, the request is forwarded to interface 3000, and when accessing www.b.com, it is forwarded to interface 4000. This simply completes the work of a reverse proxy.

You will inevitably encounter cross-domain problems when using vue development. Maybe you haven't encountered it at all. Maybe you happen to be in the same domain. Another possibility is that back-end students or operation and maintenance students have dealt with cross-domain operations. But when cross-domain is encountered in the development process, what front end should have a corresponding solution. Vue-cli is based on Node services, so we can use this service to do proxy work and temporarily solve cross-domain problems in development.

Build/webpack.config.js

Module.exports = {devServer: {historyApiFallback: true, proxy: [{context:'/ login', / / url enables proxy target when it begins with / login: 'http://www.a.com:8080', / / proxy cross-domain target interface changeOrigin: true, secure: false / / use cookieDomainRewrite: 'www.b.com' / / can be false when some https services report an error Indicates no modification}], noInfo: true}}

What is encountered in the development process can be solved in this way, but what method to use when reaching the production environment still needs to be considered. after all, it is best to make the service data more secure.

That's all for "analyzing cross-domain issues in web front-end development". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

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