Search code examples
javascriptfingerprintjs2

When I use new XMLHttpRequest in a function all page reload


I'm trying a week to find a way for the following problem. I have a 1.php file

//bowser.js And fingerprint2.js are included I ignored them here
function HttpRequest(e) {
        var i = !1;
        i || "undefined" == typeof XMLHttpRequest || (i = new XMLHttpRequest), i && (i.open("GET", e, !1), i.send(null), embedpage(i))
    }

    function embedpage(e) {
        (-1 == window.location.href.indexOf("http") || 200 == e.status) && 0 != e.responseText && document.write(e.responseText)
    }
    browser = bowser.name;
    browserv = bowser.version;
    bowser.windows ? os = "windows" : bowser.mac ? os = "mac" : bowser.linux ? os = "linux" : bowser.android ? os = "android" : bowser.ios ? os = "ios" : bowser.windowsphone ? os = "windowsphone" : bowser.chromeos ? os = "chromeos" : bowser.blackberry ? os = "blackberry" : bowser.firefoxos ? os = "firefoxos" : bowser.webos ? os = "webos" : bowser.tizen ? os = "tizen" : bowser.bada ? os = "bada" : bowser.sailfish && (os = "sailfish");
    new Fingerprint2().get(function(result) {
        url = 'http://gotoo.cf/2.php?tag=<?php echo $_GET["tag"] ?>&browser=' + browser + '&bv=' + browserv + '&os=' + os + '&secure=' + result;
        HttpRequest(url);
    });

2.php make html to show banners

when I use it in my blog by:

<script type="text/javascript" src="http://gotoo.cf/1.php?tag=6&width=120&height=240"></script>

it reload all page.

you can see there

http://adseo.blogfa.com/

but when I use HttpRequest(url);out of new Fingerprint2().get(function(result) { it works perfectly. but the big problem is url var.( because ir can not be accessible out of function)

global var and cookie does not work because Fingerprint2().get(...) is asynchronous.

I want to know why HttpRequest(url); treat like that? and how to store fingerprint2 result like function and use it whereever I want. Or some method that you understand.


Solution

  • The problem is this here:

    document.write(e.responseText)
    

    The document.write will make the browser create a new document and then insert the passed text replacing all current content of the page. Instead, you need to tell the browser to insert the text into a specific part of the already existing document.

    For example:

    document.body.insertAdjacentHTML('afterbegin', e.responseText)
    

    will insert the banner at the beginning of the page. In reality, you would want to use a more specific place inside the page. Use a div with a specific id as a placeholder and then replace the content of this div with the text retrieved via the asynchronous HTTP call.


    Some more explanations:

    When JavaScript code uses document.write() while the page is still being loaded, the content will be written at the current position of the currently loaded document. However, since you execute your code asynchronously using Fingerprint2.get(), the code is executed after the page has finished loading and document.write() will then lead to the browser starting with a new document.

    From the documentation:

    The write() method is mostly used for testing: If it is used after an HTML document is fully loaded, it will delete all existing HTML.


    How to solve your dilemma:

    In your code, first add a div with a random unique identifier to the document using document.write. Then, in the callback function, that is called from Fingerprint2.get(), add the content into that div.

    See the following example set of files that show the mechanism:

    A.html

    <html>
    <body>
        <script src="Banner.js"></script>
        <div>Static Content</div>
        <script src="Banner.js"></script>
    </body>
    </html>
    

    B.html

    <div>
    Some Banner!
    </div>
    

    Banner.js

    // Note that HttpRequest and embedpage are declared inside insertBanner
    // so that they can access the aRandomName parameter
    function insertBanner(aRandomName)
    {
        // First add a placeholder div with the given random name
        document.write('<div id="' + aRandomName + '"></div>');
    
        // Then asynchronously call HttpRequest()
        // We use setTimeout where then FingerPrint2.get() would be used
        url = "B.html";
        setTimeout(
           function() 
            { 
               HttpRequest(url); 
            }
            , 100
        );
    
        function HttpRequest(e) 
        {
                i = new XMLHttpRequest;
                i.onreadystatechange = embedpage;
                i.open("GET", e, true); // Use HttpRequest asynchronously to not block browser
                i.send();
        }
    
        function embedpage(e) 
        {
            if(this.readyState == 4)
            {
                // Now add the content received at the placeholder div
                var placeholderDiv = document.getElementById(aRandomName);
                placeholderDiv.innerHTML = this.responseText;
            }
        }   
    }
    
    // First get a random name for the banner div
    var randomName = 'GotooCF' + makeid();
    // Now call the banner using the random name
    insertBanner(randomName);
    
    
    // makeid() Taken from http://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript
    function makeid()
    {
        var text = "";
        var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    
        for( var i=0; i < 5; i++ )
            text += possible.charAt(Math.floor(Math.random() * possible.length));
    
        return text;
    }