【问题标题】:I'm implementing reCaptcha on a very large form (in PHP) -- how can I preserve form data if reCaptcha fails?我正在一个非常大的表单上实现 reCaptcha(在 PHP 中)——如果 reCaptcha 失败,我如何保存表单数据?
【发布时间】:2013-09-05 14:58:46
【问题描述】:

基本上,我有一个巨大的表格,任何人都必须重新填写它会很痛苦。我们必须实施 reCaptcha 以防止垃圾邮件机器人。

我想让它在用户输入错误验证码时,他们的表单数据不会丢失。

表单、reCaptcha 库和 reCaptcha 初始化代码位于它们自己的名为 Application.php 的文件中。此表单发布到application_confirm.phpapplication_confirm 包含另一个文件,它将表单数据处理为电子邮件格式并将其发送给管理员。

Application.php 在另一个 php 页面上是必需的(具有讽刺意味的是 application.php - 这是用户访问的页面,然后通过require('content/Application.php')从前面提到的 Application.php 包含表单 html

我真的不知道我需要做什么或需要在哪里进行验证码有效性检查 - 非常感谢任何帮助!

【问题讨论】:

  • 用 ajax 做recaptcha
  • 嗨,Emilio,您介意为我详细说明一下吗?谢谢。
  • @Prefix 没有使用 AJAX 发送验证码的安全方法。鬼鬼祟祟的用户只会关闭 JavaScript。
  • @Prefix 希望答案有所帮助。
  • @SweetieBelle 是的,我也是这么想的,我想用 PHP 保留它,如果验证码失败,只需重定向回表单并重新填充表单输入。

标签: php forms recaptcha


【解决方案1】:

我喜欢将 $_POST 数据存储到 $_SESSION 而不是 javascript 方法中。提交表单后,将 $_POST 数组推送到 $_SESSION 变量中。如果重新验证失败,请使用 $_SESSION 中的值重新加载表单。成功发布表单后,销毁会话,以便在他们返回表单时不会自动填充旧信息。

<?php
    session_start();
    $response = recaptcha_check_answer ($privatekey,
            $_SERVER["REMOTE_ADDR"],
            $_POST["recaptcha_challenge_field"],
            $_POST["recaptcha_response_field"]);
    if(isset($_POST['submit']) && !$response->is_valid)
    {
        $_SESSION['form'] = $_POST;
    }
    else
    {
        //Handle form processing
    }
?>

将输入字段的值设置为来自 $_SESSION 的值

<input type="text" name="email" value="<?= $_SESSION['form']['email'] ?>" />

【讨论】:

    【解决方案2】:

    为此滥用 JavaScript 和 localStorage...

    要求

    我假设你已经安装了 jQuery。如果没有,您将不得不将它包含在您的页面中,或者为基本的 JavaScript 重写一些函数。

    我还假设您的用户正在运行一个相对较新的浏览器(尽管您可以使用 cookie 做很多相同的事情,解释如何设置它是另一个答案)并且没有禁用 JavaScript。

    保留表单

    首先,在您希望为其存储值的每个输入对象上附加一个 input-to-store 类,然后当您的用户按下提交按钮而不是立即提交您的表单时,让它首先调用一个名为 storeValues() 的函数然后提交表格:

    function storeValues() {
        if(typeof(Storage) !== "undefined") {
            localStorage.setItem('preserve', true);
            $('.input-to-store').each(function() {
                localStorage.setItem($(this).attr('id'), $(this).val());
            });
        }
    }
    

    注意:localStorage被普遍支持,所以这种方法只支持较新的浏览器(Firefox 3.5+、Chrome 4+、IE 8+)。如果不支持此方法,您可能希望使用 else 语句在 cookie 中设置这些值。

    根据您的表单,您可能希望保留未存储在 .val() 访问器中的值。在这种情况下,添加另一个类并对每个类执行 .each() 函数。

    重新加载表单时检索值

    加载表单后,检查保留的值。如果找到,请将旧值重新加载到这些字段中:

    if(typeof(Storage) !== "undefined") {
        if(localStorage.getItem('preserve') === true) {
            localStorage.setItem('preserve', false);
            $('.input-to-store').each(function() {
                if(value = localStorage.getItem($(this).attr('id')){
                    $(this).val(value);
                }
            }
        }
    }
    

    完成后清除localStorage

    在您的成功页面上(成功提交表单后),您需要清除 localStorage 以防止您的应用程序浪费用户硬盘上的空间:

    localStorage.clear();
    

    希望这会有所帮助,尚未测试语法,但它应该让您了解如何使用 localStorage 持久化数据并绕过可怕的丢失表单。

    【讨论】:

    • 有没有办法做到这一点,而不必将 JS 混入其中?这已经是一个相当复杂的 PHP 页面,如果可能的话,我希望将其保留为 PHP 和 HTML(加上防止 JS/本地存储兼容性问题)
    • @Prefix 取决于您的验证码如何工作。如果它提交到您自己的站点,是的,将$_POST$_GET(取决于提交操作)持久保存到您的数据库中,然后在刷新时检查持久数据,然后将其重新推送到表单中并在找到时将其清除。 注意:我不建议这样做,它效率低下,并且会在您的数据库服务器上引发潜在的拒绝服务攻击(用户故意一遍又一遍地发送不正确的验证码)。 如果您不想要此漏洞,请使用 localStorage 和/或 cookie。
    【解决方案3】:

    您可以使用 AJAX 通过事件 onsubmit 将值发送到表单标签到将表单值保存到会话中的页面

    然后基本上说你有一个名为'FirstName'的输入

    <form onsubmitup='PreserverValues();'/>
    

    然后基本上你将所有输入更改为

    <input type='text' name='FirstName' value='<?php if isset($_SESSION['FirstName']) echo $_SESSION['FirstName']; ?>'/>
    

    【讨论】:

    • 他不想在每次按键时保留值(1000+ AJAX 请求似乎是一种非常低效的方法),只是在提交时。你还没有告诉他如何制作那个脚本。
    • 对。提交会更好。我试图尽可能多地解释它,因为他并没有真正提供任何代码甚至表格。
    • 嗨 - 表格太长,无法在此处发布(超过 100 个部分)。我只想保留提交时输入的数据,因此如果验证码返回 false,则重新填充表单,他们只需更改验证码。
    • 你熟悉 AJAX 还是 Javascript?
    • 是的,我不是专家,但在正确的方向上得到一些指导或推动,我可以实施一些事情。
    【解决方案4】:

    如果 reCaptcha 失败,这是一个 recaptcha 保留表单数据的工作示例?

    <script type="text/javascript">
        var RecaptchaOptions = {
            lang: 'en',
            theme: 'custom',
            custom_theme_widget: 'recaptcha_widget'
        };
    </script>               
    
    <div class="control-group">
    
        <div id="recaptcha_widget" style="display:none">
    
            <input type="text" id="recaptcha_response_field" name="recaptcha_response_field" class="required"/>
    
            <div id="recaptcha_image"></div>
    
            <div class="recaptcha_only_if_incorrect_sol" style="color:red">Incorrect please try again</div>
    
            <div><a href="javascript:Recaptcha.reload()">Get another CAPTCHA code</a></div>
        </div>
    
        <script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=YOURKEY"></script>
    
        <noscript>
        <iframe src="http://www.google.com/recaptcha/api/noscript?k=YOURKEY" height="300" width="500" frameborder="0"></iframe><br>
        <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
        <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
        </noscript>                                                 
    
        <?php
        require_once('captcha/recaptchalib.php');
        $publickey = "YOURKEY"; // you got this from the signup page
        echo recaptcha_get_html($publickey);
        ?>      
    
    </div><!-- control grp captcha --> 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 2018-12-31
      • 2015-01-23
      • 2012-01-06
      • 2015-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多