Google reCaptcha 响应“未捕获(承诺)为空”

Posted

技术标签:

【中文标题】Google reCaptcha 响应“未捕获(承诺)为空”【英文标题】:Google reCaptcha response "Uncaught (in promise) null" 【发布时间】:2019-02-22 17:24:34 【问题描述】:

我正在使用 reCaptcha v2,但无论如何在开发控制台响应 Uncaught (in promise) null(并移动 .reset() 函数)

控制台:

我的recaptcha代码:

<div class="text-xs-center" style="text-align: center; height:150px;">
    <p style="color: black;"> Complete the verification: </p>
    <div style="display: inline-block;" class="g-recaptcha" data-sitekey="xxxxxxxxxxx" data-callback="callback"></div>
</div>

我的回调函数:

function callback() 
    if (grecaptcha === undefined) 
        alert('Recaptcha non definito'); 
        return; 
    

    var response = grecaptcha.getResponse();
    console.log(response);

    if (!response) 
        alert('Coud not get recaptcha response'); 
        return; 
    

    $.ajax(
    'url' : 'validate-recaptcha.php',
    'type' : 'POST',
    'data' : 
        'response' : response   
    ,
    'success' : function(data)               
        alert('Data: '+data);
    ,
    'error' : function(request,error)
    
        alert("Request: "+JSON.stringify(request));
    
    );
    grecaptcha.reset();

还有我的validate-recaptcha.php

<?php
//debug
$fp = fopen('debug.txt', 'a');
fwrite($fp, print_r($_POST, TRUE));
fclose($fp);
//enddebug

if (empty($_POST['recaptcha'])) 
    exit('Please set recaptcha variable');

// validate recaptcha
$response = $_POST['recaptcha'];
$post = http_build_query(
    array (
        'response' => $response,
        'secret' => 'yoursecretkey',
        'remoteip' => $_SERVER['REMOTE_ADDR']
    )
);
$opts = array('http' => 
    array (
        'method' => 'POST',
        'header' => 'application/x-www-form-urlencoded',
        'content' => $post
    )
);
$context = stream_context_create($opts);
$serverResponse = @file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
if (!$serverResponse) 
    exit('Failed to validate Recaptcha');

$result = json_decode($serverResponse);
if (!$result -> success) 
    exit('Invalid Recaptcha');

exit('Recaptcha Validated');

在网上搜索,可能是.reset()函数的问题,但我不明白解决方案。

【问题讨论】:

我收到Uncaught (in promise) null 错误,原因是在为 reCaptcha 指定的回调函数中调用了未定义的函数。如果您遇到此类错误,请先仔细检查您的回调函数。 试试这个..Google Recaptcha Demo 【参考方案1】:

事实证明,当网站未在 Google recaptcha/admin Domains 区域中“注册”时也会发生这种情况。

解决方法:在recaptcha管理区添加域:

    登录您的注册验证码的 Google 帐户 在 Google 中输入“google recpatcha 管理控制台” 转到您的(生产)密钥设置 在“域”中,添加以下两个条目:
localhost
127.0.0.1
    保存并测试您的验证码。

当我从开发密钥切换到生产密钥时,我犯了这个错误。生产密钥没有任何 localhost 条目。

我将 API 响应配置为位于代理重定向之后。因此,验证是在未在 Google 管理控制台中配置的 localhost 环境中进行的,这会导致此一般错误。

感谢@Christian Žagarskas,他在评论中指出了这一点。

【讨论】:

这就是我的答案。我在本地进行测试,因此需要将 localhost 添加到 recaptcha (v3) 配置中 这是解决这个问题的正确方法,就像我们不添加网址一样,它可能不起作用 你拯救了这个开发者的日子,谢谢!需要将 127.0.0.1 添加到我的 reCaptcha 域。 绝对的救命稻草,你们俩,谢谢!【参考方案2】:

我也遇到了这个错误,我发现它与 recaptcha 回调有关(在您的情况下为 data-callback="callback")。如果您删除数据回调属性,则不会出现错误。

控制台错误Uncaught (in promise) null 表示回调正在等待一个promise。下面是一个使用 Promise 进行 recaptcha 的基本回调函数:

function callback() 
    return new Promise(function(resolve, reject)  

    //Your code logic goes here

    //Instead of using 'return false', use reject()
    //Instead of using 'return' / 'return true', use resolve()
    resolve();

  ); //end promise
;

在您的情况下,您需要将代码调整为以下内容:

function callback() 
  return new Promise(function(resolve, reject)   

    if (grecaptcha === undefined) 
        alert('Recaptcha non definito'); 
        //return;
        reject();
    

    var response = grecaptcha.getResponse();
    console.log(response);

    if (!response) 
        alert('Coud not get recaptcha response'); 
        //return;
        reject();
    

    $.ajax(
    'url' : 'validate-recaptcha.php',
    'type' : 'POST',
    'data' : 
        'response' : response   
    ,
    'success' : function(data)               
        alert('Data: '+data);
        resolve();
    ,
    'error' : function(request,error)
    
        alert("Request: "+JSON.stringify(request));
        reject();   
    
    );
    grecaptcha.reset();

  ); //end promise

这是我在 SO 中的第一个答案,所以请耐心等待,如果我忘记或遗漏了什么,请告诉我:)

【讨论】:

不幸的是,这个解决方案似乎对我不起作用。我设法将我的回调重写为 promise 变体,它可以工作,但是那个错误“未捕获的异常:请求超时”。仍然出现, @radeksvitill 我认为您在此答案范围之外还有第二个错误。 我在这里遇到了同样的问题,我没有一开始的回调......但有一天开始收到这个错误......为了后代:原来它也发生在该站点未在 Google recaptcha/admin Domains 区域中“注册”。 30 分钟后它突然又开始工作了,结果我不得不将 www.mysite、dev.mysite 和 mysite 添加为 3 个单独的允许域。 (我还没有添加 dev 子域和 *.mydomain 通配符不起作用)所以......可能需要仔细检查管理员设置。我也有保护我的域的 htaccess 密码,也将其关闭... onCompleted = function(response) console.log('captcha completed.'); $("#formContact").submit();返回真; ;这是我的回调,我得到了同样的错误,谁能帮忙解决这个问题? @Termatinator 使用 html 属性“data-callback”,就像我在上面解释的那样,而不是使用“onCompleted”javascript 事件;)【参考方案3】:

困扰我的这个错误的另一个触发因素是表单中有一个名称属性为“提交”的按钮。如果使用automatic binding example code from the reCaptcha documentation,这会出错,因为'form.submit' 将引用按钮而不是表单本身的submit() 函数。呵呵!

<html>
  <head>
    <title>reCAPTCHA demo: Simple page</title>
     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
     <script>
       function onSubmit(token) 
         document.getElementById("demo-form").submit();
       
     </script>
  </head>
  <body>
    <form id='demo-form' action="?" method="POST">
      <!-- Oops.... avoid the name="submit" below -->
      <button name="submit" class="g-recaptcha" data-sitekey="your_site_key" data-callback='onSubmit'>Submit</button>
      <br/>
    </form>
  </body>
</html>

【讨论】:

【参考方案4】:

当您的回调代码导致错误时,可能会发生这种情况。就我而言,我的回调只是引用了一些不存在的变量,我看到了同样的错误。对于这么简单的事情,非常奇怪的错误!

当我意外地在变量名后留下. 时,我也看到了同样的错误。似乎这是一个超级通用的错误,意味着fix the code in your callback!

【讨论】:

如果你的回调在别人的插件代码中怎么办? 这是我看到的错误。更一般地说,如果回调有错误,则会出现错误消息。因此,如果要对此进行调试,请尝试将回调减少为简单的 console.log('callback called') 以查看是否可以正常工作。 其他答案对我没有帮助,这个答案对我有帮助。原来我的回调函数中有一个愚蠢的错误(错字)。显然,谷歌 reCAPTCHA 回调是基于承诺的,这掩盖了“真正的”问题,你只是没有得到一个像样的堆栈跟踪。在仔细阅读和重新阅读我的回调函数之后,在发现并修复错误/错误之后,这条模糊的消息“Uncaught (in promise) null”消失了。【参考方案5】:

我觉得我应该根据我的具体经验在这里添加一个答案。我对最佳答案表示赞赏,这将是我答案的一部分。

我得到:Uncaught (in promise) null。当我在控制台中展开错误时,它是空的。

我从这里更改了我的代码:

function onSubmit(token) 
    if (grecaptcha.getResponse() !== "") 
        $('#request-form').submit();
    
    grecaptcha.reset();

对此:

function onSubmit(token) 
    return new Promise(function (resolve, reject) 

        if (grecaptcha.getResponse() !== "") 
            $('#request-form').submit();
        
        grecaptcha.reset();

    );

此更改的作用是让您在控制台中收到特定的错误消息。然后您可以继续解决您的具体问题。

【讨论】:

这对我帮助很大!太感谢了。我认为这是一些奇怪的 recaptcha 错误,但事实证明我有一个未定义的变量【参考方案6】:

类似于 John Rix 问题/解决方案。当提交元素的 id 为“提交”时,我也遇到了错误。

<!-- Avoid id="submit" below -->
<input type="submit" id="submit" value="submit">```

【讨论】:

在我的例子中,它是提交按钮的 name="submit"。更改输入按钮名称后异常消失。【参考方案7】:

就我而言,我使用的是jquery.3.4.1.slim.js,然后我改为jquery.3.4.1.min.js,错误消失了。我在ASP.NET WebForms

【讨论】:

关于我的设置的一切都是正确的。我把头发扯掉了。然后我读了这个答案。问题解决了!【参考方案8】:

我遇到了这个问题。这是因为在我的回调函数中有 jquery 代码,并且由于某种原因,我忘记了包含 jquery 脚本。所以如果你遇到这个问题,我建议你仔细检查你的回调代码的每一行。可能会逐行降低复杂性,您将得到解决方案。错误处理应该以更好的方式完成。

【讨论】:

【参考方案9】:

我使用的是 ASP.NET Core 3.1 Identity,我遇到了这个问题并通过将 jquery.validate.min.jsjquery.validate.unobtrusive.min.js 更新到 _ValidationScriptsPartial.cshtml 中的最新版本来解决它。

【讨论】:

【参考方案10】:

我遇到了同样的问题,问题是我没有将 localhost 添加到支持的域列表中。

【讨论】:

【参考方案11】:

我遇到了这个错误,因为我有:

const onChange = e => 
  e.preventDefault();
  console.log('success')


<ReCAPTCHA sitekey="yeet" onChange=onChange />

删除e.preventDefault() 删除了错误。

【讨论】:

以上是关于Google reCaptcha 响应“未捕获(承诺)为空”的主要内容,如果未能解决你的问题,请参考以下文章

Google reCaptcha v3 与 google reCaptcha Enterprise

css 将Google Recaptcha显示为#css #recaptcha #center

css 将Google Recaptcha显示为#css #recaptcha #center

如何将 Google Recaptcha v2 实施到限制访问 Google Recaptcha 的 Web 应用程序

css 使Google Recaptcha适合典型的移动视图#recaptcha #mobile #responsive

css 使Google Recaptcha适合典型的移动视图#recaptcha #mobile #responsive