简体   繁体   中英

How to detect a click inside of an iframe (cross-domain)? Aka prevent click fraud

I got a warning by my ad system provider about click fraud. No further info, all they are recommending is "hide the ads for users who click on ads too quickly'". I wrote a piece of JS script that hides all DIVs with ads for N seconds (using cookie) when clicked on, but this solution does not work as the "inner" content (with ads) is generated by an JS script that calls and renders the content from external server (as you would expect from an ad system). So, when one takes the cross-domain security into account it is kinda Catch 22. How can I detect a click inside a DIV (locally defined) of which content is rendered by an external JS and in iframe?

Example:

<div class="ad-class"> <!-- locally defined div -->
   <div id="my-id"> </div> <!-- identifies my ad in the provider's system -->
   <script>
      var foo = blah // declares the ad dimensions and stuff
      //  and renders the contextual ad in #my-id DIV
   </script>
</div>

Were it all local, solution would be easy as the internal div would inherit the parent class ("ad-class"). In case of cross-domain, this is not valid. Any tips, dudes?

You cannot detect click events in cross-domain iframe.

That put, you might have one bad option:

One of the nearest things you can do is detect that the focus moved from your window to the iframe:

window.focus(); //force focus on the currenct window;
window.addEventListener('blur', function(e){
    if(document.activeElement == document.querySelector('iframe'))
    {
        alert('Focus Left Current Window and Moved to Iframe / Possible click!');
    }
});

http://jsfiddle.net/wk1yv6q3/

However it's not reliable, loose focus does not mean a click, it could be user moving across the website using TAB .

Another problem is that, you only detect the first time focus is moved to the iframe, you do not know what user does in there, he can click a million times and you will never know.

Luizgrs inspired me this solution :

 var clickIframe = window.setInterval(checkFocus, 100); var i = 0; function checkFocus() { if(document.activeElement == document.getElementById("ifr")) { console.log("clicked "+(i++)); window.focus(); } }
 <!DOCTYPE html> <h2>Onclick event on iframe</h2> <iframe src="https://www.brokenbrowser.com/" id="ifr"></iframe>

The function detect if the iframe has the focus, if yes, the user clicked into the iframe. We then give back the focus to our main windows, which allow us to find if the user click another time.

This trick has been usefull to me for a POC on a 2 step iframe click-jacking. Getting to know when the user clicked for the first time on the iframe allowed me to reorganize my different layers to keep the illusion perfect.

The approach @Luizgrs pointed out is very accurate, however I managed to indeed detect the click event using a variation of the method:

var iframeMouseOver = false;
    $("YOUR_CONTAINER_ID")
        .off("mouseover.iframe").on("mouseover.iframe", function() {
            iframeMouseOver = true;
        })
        .off("mouseout.iframe").on("mouseout.iframe", function() {
            iframeMouseOver = false;
        });

    $(window).off("blur.iframe").on("blur.iframe", function() {
        if(iframeMouseOver){
            $j("#os_top").click();
        }
    });

The above code works like a charm on desktop if you want to add mobile support you just need to use touch events touchstart and touchend events to simulate the mouseover on mobile.

Source

Well, a while ago I found this plugin for WordPress . Obviously it does what I need -- just wondering how this guy made it to work, it does count clicks on Adsense iframe. I must have a closer look though I am not a PHP programmer. I program mainly in Python and need some solution of this kind for Django. If anyone can read the code easily, I would appreciate any help.

The plugin is searching first for any iframe wrapped by a previous specified class name.

The iframe id´s will be collected in a array and for everyone of these id´s an mouseover event will be created which fires the script which hides the class 'cfmonitor'. As a result the iframe containing ad is not visible anymore.

// IFRAME ACTION
    function iframeAction () {
        jq.each(jq.cfmonitor.iframes, function(index,element) {
            frameID = jq(element).attr('id') || false;
            if (frameID) initiateIframe(frameID);
            //alert (frameID);
        });
    }

    // INIT IFRAME
    function initiateIframe(elementID) {
        var element = document.getElementById(elementID);
        // MOUSE IN && OUT
        if (element) {
            element.onmouseover = processMouseOver;
            element.onmouseout = processMouseOut;
            //console.log("mouse on out");
        }
        // CLICKS
        if (typeof window.attachEvent !== 'undefined') {
            top.attachEvent('onblur', processIFrameClick);
        }
        else if (typeof window.addEventListener !== 'undefined') {
            top.addEventListener('blur', processIFrameClick, false);
        }
}

// IFRAME CLICKS
    function processIFrameClick() {
        // ADD A CLICK
        if(isOverIFrame) {
            //addClick();
            // Some logic here to hide the class 'cfmonitor'
            //console.log("Go");
            top.focus();
        }
}

Check this it might help. You can not detect the click event when its cross browser.

window.focus();
window.addEventListener('blur', function(e){
  if(document.activeElement == document.getElementById('Your iframe id'))
   {
    console.log('iframe click!');
   }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM