如何检测 iframe 内的点击(跨域)?又名防止点击欺诈

IT技术 javascript jquery html iframe ads
2021-03-22 07:27:39

我的广告系统提供商向我发出了关于点击欺诈的警告。没有更多信息,他们所推荐的只是“为点击广告太快的用户隐藏广告”。我写了一段 JS 脚本,在点击时隐藏所有带有广告的 DIV(使用 cookie)N 秒,但是这个解决方案不起作用,因为“内部”内容(带有广告)是由调用和呈现的 JS 脚本生成的来自外部服务器的内容(正如您对广告系统所期望的那样)。因此,当考虑跨域安全性时,它有点像 Catch 22。如何检测 DIV(本地定义)内的点击,其中的内容由外部 JS 呈现并在 iframe 中呈现?

例子:

<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>

如果都是本地的,解决方案会很容易,因为内部 div 将继承父类(“ad-class”)。在跨域的情况下,这是无效的。伙计们,有什么建议吗?

6个回答

您无法检测跨域 iframe 中的点击事件。

也就是说,您可能有一个糟糕的选择:

您可以做的最接近的事情之一是检测焦点从您的窗口移动到 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/

但是它不可靠,松散的焦点并不意味着点击,它可能是用户使用TAB.

另一个问题是,你只检测到第一次焦点移到 iframe 上,你不知道用户在那里做了什么,他可以点击一百万次,你永远不会知道。

感谢您的启发,您可能有兴趣查看我的回答,这是您的升级版。
2021-05-05 07:27:39
非常感谢你,Luizgrs。这是迄今为止最好的解决方案。ppl 使用 TAB 浏览网站的概率非常低。点击广告文字而不是链接的概率也是如此。就像我说的,在点击(或在这种情况下的任何交互)后,广告 div 被隐藏,iframe 中此类交互的时间存储在 cookie 中。如果访问者继续浏览网站,则会再次读取 cookie,并在 N 秒后再次显示广告 div。
2021-05-08 07:27:39
但是,是的,我发现广告提供商的要求有点愚蠢。顺便说一句,我想知道如何保护 Adsense div 免受点击欺诈(我现在不使用 Adsense,但一直在考虑改用它。)
2021-05-17 07:27:39
此解决方案不适用于 Firefox 的最新版本。有什么办法可以解决吗?
2021-05-20 07:27:39

Luizgrs启发了我这个解决方案:

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>

该函数检测 iframe 是否具有焦点,如果是,则用户单击 iframe。然后我们将焦点返回到我们的主窗口,这使我们能够找到用户是否再次单击。

这个技巧对我在两步 iframe 点击劫持上的 POC 很有用。了解用户第一次在 iframe 上单击的时间使我能够重新组织不同的图层以保持完美的错觉。

我为动态 iframe 使用了类似的脚本,而您的 window.focus 是我需要的缺失部分!谢谢你。
2021-05-14 07:27:39

@Luizgrs 指出的方法非常准确,但是我确实设法使用该方法的变体来检测点击事件:

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();
        }
    });

上面的代码在桌面上就像一个魅力,如果你想添加移动支持,你只需要使用触摸事件 touchstarttouchend事件来模拟移动设备上的鼠标悬停。

来源

或者为支持它的浏览器使用指针事件而不是鼠标/触摸。
2021-04-25 07:27:39

好吧,不久前我发现了这个 WordPress 插件显然它满足了我的需求——只是想知道这个人是如何让它工作的,它确实计算了 Adsense iframe 上的点击次数。虽然我不是 PHP 程序员,但我必须仔细看看。我主要用 Python 编程,需要一些此类的 Django 解决方案。如果有人可以轻松阅读代码,我将不胜感激。

该插件首先搜索由先前指定的类名包装的任何 iframe。

iframe id 将被收集在一个数组中,对于这些 id 中的每一个,将创建一个鼠标悬停事件,该事件触发隐藏类“cfmonitor”的脚本。因此,包含广告的 iframe 不再可见。

// 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();
        }
}