Front end cross domain problem solving process record I used

Posted by aconite on Sun, 19 Jan 2020 05:00:43 +0100

First of all, I'm lazy. I haven't recorded my work for a long time. I hope I don't forget my original intention.

Recently, I have such a demand. We are equipment software companies. Therefore, one of the functions is to modify the IP and port of our own management interface. After the modification, we need to jump to a new page. There will be a problem here, that is, the original page needs to communicate with the new IP and port, which involves cross domain problems. There are many kinds of cross domain problems to solve online problems. I only record here I used two.

The architecture of our project is that the front-end is sent to the back-end through Apache reverse proxy. Therefore, cors is a cross domain method. We should configure the cors for Apache (originally thought to be the back-end for cors configuration). The following code needs to be added to Apache:

<Directory />
Header set Access-Control-Allow-Origin *
</Directory>

To restart Apache after configuration, we need the back-end cooperation to do one thing, because at this time we can call the url of the new IP, but when the browser detects cross domain, it will send a pre check url with the request method OPTIONS. This url needs the back-end to cancel the header information detection, and then the browser will send a real url after it returns successfully, so we can Cross domain access of will succeed

After this process, we can call our IP in any page. To be honest, it's very insecure. Of course, * can be changed to a fixed url, so we can only call our functions across domains in a fixed url page. But this does not apply to our needs, or we can do it but it's troublesome, because I need to trouble the backend to fix this * first Change to the user's new IP, and then he changes the underlying IP. So give it up

Then I need a cross domain method that does not need to sacrifice security, aiming at modifying the IP or port of the management port. That is to realize cross domain through iframe. Specifically, we need to give an invisible iframe box to the original page, and then give a tag a below. Point the target attribute to the name attribute of iframe, so that when clicking the tag a, the new page will be displayed in iframe instead of opening a new browser window. Then, if we monitor the page loading in iframe, we can know whether the modified new IP or port is successful. The twist is that I only monitored the loading of iframe at the beginning. If I load the unsuccessful url eight times in a row in Google browser, it will be returned to the failed page. So if we only monitor the loading of iframe, we will get the error eight times Error monitoring: because the real url is not a successful communication, but a failed page returned by the browser itself, we need to monitor the content loaded on the iframe page. Unfortunately, I tried many times and failed to get the dom inside, so I can only send a message to my current page from the page after the successful communication of iframe, using window.parent.postMessage('ok ',' * '),

window.addEventListener('message',function (e) {if(e.data=='ok') {}}) monitoring, I will show the relevant code below:
//This code is placed in the HTML of the configuration page that needs to jump
<div style="z-index: 999;display: none;position: absolute;">
       <iframe id="login-frame-1" name="login-frame-1"></iframe>
       <a href="#" id="login-a" target="login-frame-1">jump</a>
</div>

//vue data initialization
data() {
        return {
            loginGetatt:0,
            loginReady: false,
            cancle_setTimeOut:undefined,
            
        }
    },

// This code is executed after the page is loaded successfully, and vue is placed in the mounted / / loginReady is the status label after the page is loaded successfully. The original status needs to be set to false, and vue is set in data()
window.addEventListener('message',function (e) {
            console.log(e)
            if(e.data=='ok'){
                self.loginReady = true
            }
})

//This code is placed before modifying the API of IP or port
setTimeout(function () {
        //You can add the judgment logic of whether or not you need to jump, because you don't need to jump to change the ipv6 address on the IPV4 page
        //url the new url address modified by the user
        document.getElementById('login-a').href = url+'/login'
        self.loginGet(url)
},3000)

//This logic is to click the a tag every 3 seconds. If self.loginreready is true, it means that the page of the new IP is loaded successfully, or the current window will jump to a new URL directly after timeout
loginGet(url){
            let self = this
            self.loginGetatt++ //self.loginGetatt initial value is 0, vue is set in data()
            self.cancle_setTimeOut=setTimeout(function () {
                document.getElementById('login-a').click()
                if(self.loginReady||self.loginGetatt>30){\
                    window.location.href=url
                }else{
                    self.loginGet(url)
                }
            },3000)
        },

//vue destroys the setTimeout and listening events of this binding
destroyed(){
        let self = this
        clearTimeout(this.cancle_setTimeOut);
        window.removeEventListener('message',function (e) {
            console.log(e)
            if(e.data=='ok'){
                self.loginReady = true
            }
        })
    },

//This method is placed in the js of the new jump page. Once the page is loaded, a message will be sent to the window to judge whether the page is loaded successfully in iframe
function checkout_iframe() {
    window.parent.postMessage('ok','*')
}

In summary, it is not appropriate to modify the Apache configuration in this requirement. However, if we can guarantee the speed of IP modification at the back end, that is, sending new IP within eight consecutive times, we'd better use iframe to bind the onload event, because when we modify an IP that has not been logged in, even after the back end modification is successful, Firefox or Google will add it in the iframe box Load the intercepted page, so we can't send the success message to the current page. If we use the onload event of iframe, we can judge that the new page is loaded successfully, but it must be within eight communications (Firefox doesn't have this problem)

Published 25 original articles, won praise 5, visited 20000+
Private letter follow

Topics: Apache Vue Attribute Google