Recaptcha v2在重置时会抛出错误,并且从DOM中删除其容器元素

Det*_*iel 13 javascript recaptcha

当我显式渲染Recaptcha v2然后在从DOM中删除它之前重置它,大约40秒后我在浏览器控制台中出错.

我有一个可以用来重现问题的JSFiddle.

这是相关的代码摘录:

const recaptchaHolder = document.getElementById('...');
const recaptchaWidgetId = grecaptcha.render(recaptchaHolder, {/*...*/});
// then later
grecaptcha.reset(recaptchaWidgetId);
recaptchaHolder.parentElement.removeChild(recaptchaHolder);
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

未知(承诺)超时

使用以下stacktrace(实际的堆栈跟踪可能会有所不同,因为它发生在严重缩小的代码中):

setTimeout (async)      
J           @   recaptcha__en.js:100
(anonymous) @   recaptcha__en.js:285
tb          @   recaptcha__en.js:284
mj          @   recaptcha__en.js:456
(anonymous) @   recaptcha__en.js:458
Run Code Online (Sandbox Code Playgroud)

我试图利用文档中'error-callback'参数来捕获此错误,但这没有帮助 - 错误仍未被捕获,并且不会调用此回调.

另一个观察:如果我grecaptcha.reset在从DOM中删除元素之前省略调用,则不会发生错误.但是,它可能会导致UI不一致:如果用户受到recaptcha的挑战(例如,使用图像),并且只是从DOM中删除元素而不调用grecaptcha.reset,则不会从DOM中清除挑战HTML.

我正在寻找处理上述错误或以不同方式处理recaptcha删除的方法(如果我现在做错了)

Rad*_*til 2

经过几个小时后,我只找到了这个解决方案,请参阅https://jsfiddle.net/4mLhcksq/

在删除 Recaptcha 元素之前有setTimeout60 秒(我猜可能更短)暂停grecaptcha.reset(),然后再暂停一次。实际上,即使我不删除 Recaptcha 元素,仅重置它,我也遇到了同样的问题。

const holder = getRecaptchaHolder();
holder.style.display = 'none'; //element disappears for users
setTimeout(function() {
  grecaptcha.reset(recaptchaWidgetId);
  setTimeout(function() { //we have to wait a while before removing element
    holder.parentElement.removeChild(holder);
  }, 1000);
}, 60000);
Run Code Online (Sandbox Code Playgroud)

我对这个解决方案并不感到特别自豪。让我们希望有人能提供更好的。