如何使用JavaScript重新加载ReCaptcha?

210

我有一个带有AJAX的注册表单,所以当出现错误(例如用户名已被使用)时,我想刷新ReCaptcha图像。

我正在寻找与ReCaptcha兼容的代码,使用JavaScript重新加载它。


1
不用理会。如果用户名已被占用,为什么要更改验证码? - SLaks
20
可能是因为他先检查验证码再检查用户,一旦使用了验证码,它就不再有效。如果反过来做,恶意用户可以轻松地欺骗服务器,并通过暴力破解获取所有用户列表而不需要验证码的干扰。 - Tomasz Nurkiewicz
1
@TomaszNurkiewicz 更新:恶意用户将无法提交相同的re-captcha以进行验证超过一次。因此,这里不可能进行暴力破解。刷新验证码的原因只是为了让用户重新输入它。 - tonysepia
我相信一个有技能的攻击者可以利用时间攻击来找出哪些数据是错误的,这取决于机器人验证的位置;我更喜欢将我的验证作为第一项检查,并立即拒绝任何失败的请求,这也有助于减轻服务器负载,因此当它们被拒绝时我不会执行数据库查询。 - Steve Byrne
9个回答

425

对于reCaptcha v2,请使用:

grecaptcha.reset();

如果您正在使用reCaptcha v1(可能不是):

Recaptcha.reload();
如果窗口中已经加载了ReCaptcha,那么这将起作用。

21
对于使用新版reCAPTCHA的人:现在代码行已更改为grecaptcha.reset();文档)。 - SebiH
我在我的React应用程序中使用grecaptcha.reset();,它完美地运行。 - yussan
4
如果您不确定grecaptcha已加载,请使用if (window.grecaptcha) grecaptcha.reset();。该代码将重置grecaptcha并确保其已正确加载。 - fred727
尽管这会重新加载验证码,但验证码响应的字段值似乎没有被删除,使我的表单仍然有效。 - Damian Green

72

如果您正在使用版本 1

Recaptcha.reload();

如果您正在使用版本2

grecaptcha.reset();

3
复制了被接受的答案并在3年后重新发布。嗯。 - Paul Danelli
2
@PRWhitehead 请查看编辑历史记录。顺便说一下,感谢您的投票。 - Dasun
我已经编辑过我的回答了,而你还没有编辑过你的回答。而且你在三个月之后才添加了回答,这已经影响到了初始回答的相关性,而且这是在多年之后才添加的。我给你的回答点了踩,因为被接受的回答更有用。 - Paul Danelli
3
我添加了这个答案是因为我遇到了同样的问题。尽管被接受的答案在当时反映了正确的答案,但对我来说并不够清楚。至少对我来说是这样,所以我决定添加一个新的答案,并进行明确区分(被接受的答案未能注明版本之间的差异)。 - Dasun

53

12
grecaptcha.reset(opt_widget_id)

重置reCAPTCHA小部件。可选择传递小部件ID,否则该函数将重置第一个创建的小部件。(来自Google网页)


它只重置了页面上的第一个验证码。 - Maxwell s.c
@Maxwells.c 你有没有看过这篇文章?如果需要,你可以传递一个小部件ID并删除第n个小部件。如果不传递,则将重置第一个小部件。 - Kutalia
1
Widget id是什么?我尝试传递recaptcha <div>的html id,但出现了“无效的recaptcha客户端id”错误。我认为我需要显式地渲染widget,因为我认为render()方法返回我所需的id。 - Pete
opt_widget_id是可选的,它是从render调用返回的id,但如果缺失,它将引用第一个创建的recaptcha部件(如果您只有一个部件,那么这就足够了)。 - frzsombor

9
或者您可以模拟点击刷新按钮。
// If recaptcha object exists, refresh it
    if (typeof Recaptcha != "undefined") {
      jQuery('#recaptcha_reload').click();
    }

1
由于某些原因,我的页面上Recaptchagrecaptcha都未定义。这个方法对我有用,稍作修改即可:if( $("#recaptcha_reload").length > 0 ){ .... - Nate-Bit Int
我使用它来知道数组迭代何时完成,而无需计算其元素。 - m3nda

7

试一下这个

<script type="text/javascript" src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
          function showRecaptcha() {
            Recaptcha.create("YOURPUBLICKEY", 'captchadiv', {
              theme: 'red',
              callback: Recaptcha.focus_response_field
            });
          }
 </script>

<div id="captchadiv"></div>

如果您调用showRecaptcha,captchadiv将会填充一个新的reCAPTCHA实例。

你可以更改你的代码并在onload时调用showRecaptcha吗?这对你有帮助吗? - Tim

3

对于AngularJS的用户:

$window.grecaptcha.reset();

1
在我的情况下,没有 $—— window.grecaptcha.reset(); - tonysepia

1
如果你正在使用新的 reCAPTCHA 2.0,请使用以下内容: 对于后端代码:
ScriptManager.RegisterStartupScript(this, this.GetType(), "CaptchaReload", "$.getScript(\"https://www.google.com/recaptcha/api.js\", function () {});", true);

对于简单的 JavaScript

<script>$.getScript(\"https://www.google.com/recaptcha/api.js\", function () {});</script>

0
如果在同一页上有多个reCAPTCHA小部件,则reset()方法将默认为第一个,除非指定widgetId。该API没有提供在代码中查找widget Id的简单或可靠的方式。解决方法是显式加载小部件并将widget Id存储在数据属性中。
<script src="https://www.google.com/recaptcha/api.js?onload=recaptchaLoaded&render=explicit"></script>

<script>
    function recaptchaLoaded() {
    
        document.querySelectorAll('.g-recaptcha').forEach((el, i) => {
            var widgetId = grecaptcha.render(el);
            el.setAttribute('data-grecaptcha-id', widgetId);
        });
    
    }

    document.getElementById("mybutton").addEventListener("click", (event) => {
        var widgetId = document.getElementById("mycaptcha").getAttribute('data-grecaptcha-id');
        grecaptcha.reset(widgetId);
    });

</script>

请注意,脚本URL必须包括render=explicit和您的onload回调方法的名称。

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