reCaptcha 问题:即使我在 angularJS 中添加了标头,所请求的资源上也不存在“Access-Control-Allow-Origin”标头始终显示

Posted

技术标签:

【中文标题】reCaptcha 问题:即使我在 angularJS 中添加了标头,所请求的资源上也不存在“Access-Control-Allow-Origin”标头始终显示【英文标题】:reCaptcha issues : No 'Access-Control-Allow-Origin' header is present on the requested resource always shows even I have add header in angularJS 【发布时间】:2015-01-13 21:45:46 【问题描述】:

我在 google reCaptcha 中有一些问题 验证码很好,可以正常显示,但是当我提交它时,当我向

发送 POST 请求时出现连接问题

https://www.google.com/recaptcha/api/verify

这里是错误日志:

XMLHttpRequest cannot load https://www.google.com/recaptcha/api/verify. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3002' is therefore not allowed access. The response had HTTP status code 405.

这里是我的html代码:

<div class="form-group" style="margin-bottom: 20px;">
    <div class="text-center center-block">
      <div class="text-center center-block" vc-recaptcha
      tabindex="3"
      theme="white"
      key="model.key"
      lang="en"
           </div>
    <button class="btn" ng-click="submit()">Submit</button>
  </div>
</div>

这是我的 controller.js

 $scope.model = 
            key: //THIS IS MY PUBLIC KEY
        ;
 $scope.submit = function() 

            var valid;
            var ip;
            $http.jsonp('http://ipinfo.io/?callback=JSON_CALLBACK')
                    .success(function(data) 
                        console.log("stateChangeStart ip = " + data.ip);
                        ip = data.ip;
                    ).then(function() 
                $http(
                    method: 'POST',
                    headers: 
                        'Access-Control-Allow-Origin': '*',
                        'Access-Control-Allow-Methods': 'POST'
                    ,
                    url: 'https://www.google.com/recaptcha/api/verify',
                    data: 
                        'privatekey': /* THIS IS MY PRIVATE KEY */,
                        'remoteip': ip,
                        'challenge': vcRecaptchaService.data().challenge,
                        'response': vcRecaptchaService.data().response
                    

                ).success(function(result, status) 
                    console.log('it work');

                ).error(function(data, status, headers, config) 
                    console.log('error');

                );

            );
        ;

我在那里添加了标题,但它总是说

请求中没有“Access-Control-Allow-Origin”标头 资源

有人可以帮助我吗? 谢谢你

更新:

我正在使用 chrome,并且我已经通过这个插件在我的 Chrome 中启用了 CORS:

enabled CORS in chrome

现在它给了我另一个错误:

XMLHttpRequest cannot load https://www.google.com/recaptcha/api/verify. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:3002' is therefore not allowed access. 

我将我的 controller.js 更改为:

 $scope.model = 
            key: //THIS IS MY PUBLIC KEY
        ;
 $scope.submit = function() 

            var valid;
            var ip;
            $http.jsonp('http://ipinfo.io/?callback=JSON_CALLBACK')
                    .success(function(data) 
                        console.log("stateChangeStart ip = " + data.ip);
                        ip = data.ip;
                    ).then(function() 
                $http(
                    method: 'POST',
                    headers: 
                        'Access-Control-Allow-Origin': 'http://localhost:3002',
                        'Access-Control-Allow-Methods': 'POST, GET, OPTIONS'
                    ,
                    url: 'https://www.google.com/recaptcha/api/verify',
                    data: 
                        'privatekey': /* THIS IS MY PRIVATE KEY */,
                        'remoteip': ip,
                        'challenge': vcRecaptchaService.data().challenge,
                        'response': vcRecaptchaService.data().response
                    

                ).success(function(result, status) 
                    console.log('it work');

                ).error(function(data, status, headers, config) 
                    console.log('error');

                );

            );
        ;

但该错误总是显示,请帮助我。

【问题讨论】:

【参考方案1】:

很多这样的东西真的很令人困惑。我们看到上面的 cmets 说“不要从客户端验证”。但是,如果您像我一样,您只是想让它首先在开发中工作,而此时我并不真正关心安全性。但是,我没有意识到 Chrome 比 Web 服务器更严格! Chrome 不会让您在不先做两件事的情况下执行验证 Google 响应的步骤:

    安装 CORS chrome 插件 在发送帖子之前将this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); 添加到标题中。 (至少在 angular2 中)

显然,您不能指望所有用户都安装 Chrome CORS 扩展程序,而且您不想将您的秘密存储在客户端中,这真的很糟糕。因此,在您开始开发后,您需要设置一个小型网络服务器,该服务器将接受来自您的客户端的此请求并将其转发给 Google,然后将响应发送回您的客户端。

附:其他让我感到困惑的事情是人们说要添加this.headers.append('Access-Control-Allow-Origin', '*');,但这是您在设置网络服务器时应用的设置,这与来自客户端的请求无关。我一直试图将其应用于我的客户端 Angular http 请求,认为这将是最终的解决方案。

【讨论】:

是的,我只是想测试一下 POST,Chrome 开发工具只是我手头上的第一个 Web 请求工具。意识到这一点,放弃在 Chrome 中尝试,改用 PowerShell。现在工作【参考方案2】:

在我的情况下,我使用 reCapchaLib 并修复了这个错误:https://github.com/google/recaptcha/blob/1.0.0/php/recaptchalib.php

并使用此代码 PHP:

<?php
error_reporting(E_ALL ^ E_NOTICE);  //variables not declared warning off

// tu clave secreta
$secret = "xxxxxx";   //get from https://www.google.com/recaptcha/
// tu site key
$sitekey = "xxxxxxx";  //get from https://www.google.com/recaptcha/


require_once "recaptchalib.php";

$response = null; 
$reCaptcha = new ReCaptcha($secret);


if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST') 
    if ($_POST["g-recaptcha-response"]) 
            $response = $reCaptcha->verifyResponse(
            $_SERVER["REMOTE_ADDR"],
            $_POST["g-recaptcha-response"]
        );
    

    echo "<h2>Valores del formulario</h2>";

    if (isset($_POST["nombre"]))
        $nombre = $_POST["nombre"];
        echo "<p>nombre: $nombre</p>";  
    

    if ($response != null && $response->success) 
        echo "<font color='blue'>Captcha Ok!</font>";
    
    else
        echo "<font color='red'>Error en Captcha!</font>";



?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="language" content="es">

    <title>Test Capcha</title>

    <!-- reCAPTCHA Script -->
    <script src='https://www.google.com/recaptcha/api.js'></script>

</head>

<body >

<div class="container">
    <div class="row">
        <div class="col-lg-12 text-center">
            <h2 class="section-heading">Test reCAPTCHA con formulario Post y PHP</h2>
        </div>
    </div>
    <div class="row">
        <div class="col-lg-12">
            <form name="sentMessage" id="contactForm" novalidate method="POST" action="?">
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="Nombre *" id="nombre" name="nombre" required data-validation-required-message="Ingrese nombre">
                            <p class="help-block text-danger"></p>
                        </div>

                        <div class="clearfix"></div>
                        <div class="col-lg-12 text-center">
                            <div id="success"></div>
                            <center><div class="g-recaptcha" data-sitekey="<?php echo $sitekey; ?>"></div><br></center>
                            <button type="submit" class="btn btn-xl">Enviar Mensaje</button>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<script   src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
</body>
</html>

【讨论】:

【参考方案3】:

您无法使用来自 CLIENT 的密钥验证您的客户端答案。您必须仅从服务器端执行此操作。因此,请更改代码以转到您的服务器(WebAPI 等),然后从那里执行 POST 到 Google URI。它应该工作。否则,进行此检查没有任何意义 - 您正在共享您的密钥......

【讨论】:

以上是关于reCaptcha 问题:即使我在 angularJS 中添加了标头,所请求的资源上也不存在“Access-Control-Allow-Origin”标头始终显示的主要内容,如果未能解决你的问题,请参考以下文章

reCAPTCHA v3 not working angular 6 - 执行错误

Angular:如何重置 matChipList 输入字段和 Google Recaptcha?

如何将 Firebase 隐形 reCAPTCHA 用于 Angular Web 应用程序?

即使对于两个不正确的单词,reCAPTCHA 也可以验证为有效

即使使用 ASP.NET CORE 登录,我在 Angular 中也有 401 Unauthorized

ReCaptcha - Chrome 隐藏扩展