如何检查Google Recaptcha V2难题是否显示?

5
我正在尝试在Recaptcha显示拼图而不是复选框时调整容器div的大小。这通常发生在单击复选框后。我该怎么做?
我知道有些条件会强制Recaptcha V2显示一个拼图而不是复选框。然而,API没有返回属性或事件来指示发生了这种变化。是否有一种方法可以通过JavaScript或API识别Recaptcha V2是否显示拼图?
注意:这将是在API url中没有指定fallback=true的情况下。

它是否在iframe中打开Recaptcha?您能否检查页面上是否存在具有这些类的内容? - krillgar
它们会向您的页面添加HTML。您需要轮询您的页面并查找此类名称g-recaptcha-bubble-arrow - 查找变异可能有所帮助:https://dev59.com/q3A75IYBdhLWcg3wlqAT - colecmc
1
它确实在iframe中打开。我查看了一些元素及其生成的id,但是我无法使用DOM操作来定位这些CSS选择器。 - Shayan Zafar
由于您无法访问 iframe 中的元素,我认为您最好的选择是在调用之前和之后检查 iframe 的大小。然而,考虑到您正在尝试确定它是拼图还是复选框,您编写的任何代码都将非常脆弱。 - krillgar
我觉得API应该在决定渲染谜题而不是复选框时提供一些属性或钩子。虽然我不确定我的想法是否完全正确! - Shayan Zafar
2个回答

3
很遗憾,谷歌没有API事件来跟踪这个,但是我们可以使用Mutation Observer Web API来自己跟踪Google API对DOM的更改。它被浏览器很好地支持:enter image description here
首先,我们需要创建一个目标元素,以便观察Google iframe的出现。我们将把document.body作为目标,因为iframe将附加到它上面。
const targetElement = document.body;

然后我们需要为MutationObserver创建一个配置对象。在这里,我们可以指定我们将跟踪DOM更改的确切内容。请注意,默认情况下所有值都为“false”,因此我们只能保留“childList”-这意味着我们仅观察目标元素(在我们的情况下是document.body)的子节点更改:

const observerConfig = {
    childList: true,
    attributes: false,
    attributeOldValue: false,
    characterData: false,
    characterDataOldValue: false,
    subtree: false
};

然后我们需要创建一个函数,当观察者检测到我们在配置对象中指定的特定类型的DOM更改时,将调用该函数。第一个参数表示Mutation Observer对象的数组。

function DOMChangeCallbackFunction(mutationRecords) {
    mutationRecords.forEach((mutationRecord) => {
        if (mutationRecord.addedNodes.length) { //check only when notes were added to DOM
            var reCaptchaParentContainer = mutationRecord.addedNodes[0];
            var reCaptchaIframe = reCaptchaParentContainer.querySelectorAll('iframe[title*="recaptcha"]');

            if (reCaptchaIframe.length) { // Google reCaptcha iframe was loaded
                console.log('Yay!');
                reCaptchaObserver.disconnect(); // We don't want to observe more DOM changes for better performance
                // Challenge was loaded -- DO SOMETHING HERE
            }
        }
    });
}

那就差不多了。唯一剩下的是实例化观察者本身并开始观察DOM更改:
const reCaptchaObserver = new MutationObserver(DOMChangeCallbackFunction);
reCaptchaObserver.observe(targetElement, observerConfig);

希望这有所帮助 :)


0

以下是使用 setInterval 实现的方法。如果用户从未勾选复选框,这可能会导致浏览器崩溃。您可能希望延迟运行此操作,直到他们开始填写表单或等待他们将鼠标悬停/聚焦在 reCaptcha 元素上。您还可以使用更具体的选择器(通过将您的 reCaptcha 包装在 div 中)以防其他 iframe 在代码中使用相同的标题。如评论中所述,使用 mutationObserver 是一个更好的想法。希望这能满足您的需求。

function isPuzzleDisplayed (selector) {
  /**
   * @param {string} selector
   * @returns boolean - if the specified element exists
   */
    return document.querySelectorAll(selector).length >= 1;
}

var timer = setInterval(function () {
  /**
   * Check if element exists every 0 seconds.
   * If it does, kill timer, else keep running forever!
   * WARNING! This is not performant.
   */
    if (isPuzzleDisplayed('iframe[title*="recaptcha challenge"]')) {
        console.log('But this is how you do it!');
        /* run your code here */
        clearInterval(timer);
        timer = 0;
    } else {
        console.log('It is true the Api however does not return a property or event that would indicate that this change has happened. >', timer);
    }
}, 0);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接