多个 Google 隐形 reCaptcha 在第一个之后返回 "Unable to post message to https://www.google.com"

Multiple Google Invisible reCaptcha returning "Unable to post message to https://www.google.com" after first

我有一个网站,人们可以通过一系列投票按钮(每件 3 个按钮代表各种状态,10 到 15 件)大约每 30 分钟记录少量事物的状态。我正在尝试实施 Google 的 Invisible reCaptcha 以防止我收到一些机器人垃圾邮件。

我已经成功实施了 Invisible reCaptcha,它在第一次投票时工作正常,但在同一页面上的任何后续投票中,我从控制台收到以下错误

[Error] Unable to post message to https://www.google.com. Recipient has origin https://example.com.

    postMessage
    l (recaptcha__en.js:210:171)
    (anonymous function)
    (anonymous function) (recaptcha__en.js:54:445)
    Lf (recaptcha__en.js:58:203)
    Gf (recaptcha__en.js:58:91)
    F (recaptcha__en.js:57:201)
    nf (recaptcha__en.js:51:1190)
    promiseReactionJob

我的实现如下

这是当用户按下按钮时调用的函数。我向它传递了一些变量,这些变量稍后会用于实际记录选票,尽管为了测试我只是让它将它们打印到控制台。回调中的 console.log 命令将替换为对稍后实际记录投票的函数的调用。

function buttonPress(typeVote, value, e, thing) {

  //Create a unique name for the captcha's div 
  var captchaName = value + "captcha";

  //e is a reference to the div holding the things' button
  //so we add the captcha's div after it
  $($(e).parent()).after("<div id='" + captchaName + "'></div>");

  //Render the captcha
  grecaptcha.render(captchaName, {
              sitekey: 'SITE_KEY_HERE', size: 'invisible',
              callback: function(token) {

                            //This will be replaced with a call to the function
                            //that actually logs the votes with an AJAX call.
                            console.log("TOKEN: " + token + "THING: " + thing + "Vote: " + typeVote);

                            //Remove the captcha div so we can recreate if user 
                            //votes again
                            $(value + 'captcha').remove();

                          }});
  //Test the user
  grecaptcha.execute();

  //By default the captcha badge is appended to the div the captcha
  //is contained in. That is hiding it behind content so move it to 
  //the end of the body tag so it's visible
  $('body').append($('.grecaptcha-badge'));
}

然后在关闭 </body> 标记之前的页面底部,我导入 Google reCaptcha 库。

<script src="https://www.google.com/recaptcha/api.js" async defer ></script>

当 Google 谈论您可以用来调用执行或重置函数的可选小部件 ID 时,它们实际上并不是指您分配给创建小部件的 div 的 ID而是渲染函数返回的唯一 ID。

您必须将该函数分配给一个变量,然后将该变量用作传递给执行或重置函数的参数。

function buttonPress(typeVote, value, e, thing) {

  //Create a unique name for the captcha's div 
  var captchaName = value + "captcha";

  //e is a reference to the div holding the things' button
  //so we add the captcha's div after it
  $($(e).parent()).after("<div id='" + captchaName + "'></div>");

  //Render the captcha
  var widgetReference = grecaptcha.render(captchaName, {
              sitekey: 'SITE_KEY_HERE', size: 'invisible',
              callback: function(token) {

                            //This will be replaced with a call to the function
                            //that actually logs the votes with an AJAX call.
                            console.log("TOKEN: " + token + "THING: " + thing + "Vote: " + typeVote);

                            //Remove the captcha div so we can recreate if user 
                            //votes again
                            grecaptcha.reset(widgetReference);
                            $(value + 'captcha').remove();

                          }});
  //Test the user
  grecaptcha.execute(widgetReference);

  //By default the captcha badge is appended to the div the captcha
  //is contained in. That is hiding it behind content so move it to 
  //the end of the body tag so it's visible
  $('body').append($('.grecaptcha-badge'));
}