Detect when query window is closed for google recaptcha

I am using an invisible Google tooltip. Is there any way to detect when the call window is closed? In the query window, I mean the window in which you must select some images for verification.

Currently, I am putting on a button that displays a recaptcha call, after clicking the button. No other request window may be requested for the user.

I call the render function programmatically:

grecaptcha.render(htmlElement, { callback: this.verified, expiredCallback: this.resetRecaptcha, sitekey: this.siteKey, theme: "light", size: "invisible" });

I have 2 callback functions connected to the tested resetRecaptcha functions that look like this:

function resetRecaptcha() {
        grecaptcha.reset();
    }

function verified(recaptchaResponse)
{
/*
which calls the server to validate
*/
}

I would suggest that grecaptcha.render has another callback that is called when the request screen is closed without checking by the user, selecting images.

+10
3

, API .

. , Google reCaptcha . reCaptcha, , , :

  • iframe src: "google.com/recaptcha/api2/bframe"
  • CSS opacity: 0,

 

// to begin: we listen to the click on our submit button
// where the invisible reCaptcha has been attachtted to
// when clicked the first time, we setup the close listener
recaptchaButton.addEventListener('click', function(){
    if(!window.recaptchaCloseListener) initListener()

})

function initListener() {

    // set a global to tell that we are listening
    window.recaptchaCloseListener = true

    // find the open reCaptcha window
    HTMLCollection.prototype.find = Array.prototype.find
    var recaptchaWindow = document
        .getElementsByTagName('iframe')
        .find(x=>x.src.includes('google.com/recaptcha/api2/bframe'))
        .parentNode.parentNode

    // and now we are listening on CSS changes on it
    // when the opacity has been changed to 0 we know that
    // the window has been closed
    new MutationObserver(x => recaptchaWindow.style.opacity == 0 && onClose())
        .observe(recaptchaWindow, { attributes: true, attributeFilter: ['style'] })

}

// now do something with this information
function onClose() {
    console.log('recaptcha window has been closed')
}
+14

IE .include() Array.from(), :

Array.from Internet Explorer

.. & & # 39;

:

function initListener() {

              // set a global to tell that we are listening
              window.recaptchaCloseListener = true

              // find the open reCaptcha window

                    var frames = Array.from(document.getElementsByTagName('iframe'));
                    var recaptchaWindow;

                    frames.forEach(function(x){

                        if (x.src.includes('google.com/recaptcha/api2/bframe') ){
                            recaptchaWindow = x.parentNode.parentNode;
                        };

                    });

              // and now we are listening on CSS changes on it
              // when the opacity has been changed to 0 we know that
                // the window has been closed

                new MutationObserver(function(){
                    recaptchaWindow.style.opacity == 0 && onClose();
                })
                  .observe(recaptchaWindow, { attributes: true, attributeFilter: ['style'] })

            }
+1

My decision:

let removeRecaptchaOverlayEventListener = null
const reassignGRecatchaExecute = () => {
  if (!window.grecaptcha || !window.grecaptcha.execute) {
    return
  }
  /* save original grecaptcha.execute */
  const originalExecute = window.grecaptcha.execute
  window.grecaptcha.execute = (...params) => {
    try {
      /* find challenge iframe */
      const recaptchaIframe = [...document.body.getElementsByTagName('iframe')].find(el => el.src.match('https://www.google.com/recaptcha/api2/bframe'))
      const recaptchaOverlay = recaptchaIframe.parentElement.parentElement.firstElementChild
      /* detect when the recaptcha challenge window is closed and reset captcha */
      !removeRecaptchaOverlayEventListener && recaptchaOverlay.addEventListener('click', window.grecaptcha.reset)
      /* save remove event listener for click event */
      removeRecaptchaOverlayEventListener = () => recaptchaOverlay.removeEventListener('click', window.grecaptcha.reset)
    } catch (error) {
      console.error(error)
    } finally {
      originalExecute(...params)
    }
  }
}

Call this function after starting window.grecaptcha.render()and beforewindow.grecaptcha.execute()

And don't forget to remove the event listener: removeRecaptchaOverlayEventListener()

0
source

Source: https://habr.com/ru/post/1675124/


All Articles