当单个页面上存在 2 个表单时,如何使用 jQuery 表单验证插件验证 reCaptcha?

Posted

技术标签:

【中文标题】当单个页面上存在 2 个表单时,如何使用 jQuery 表单验证插件验证 reCaptcha?【英文标题】:How to validate reCaptcha using jQuery Form Validation plugin when 2 forms are present on a single page? 【发布时间】:2020-06-13 03:55:36 【问题描述】:

所以我有一个页面,其中有两种语言翻译,一种是罗马尼亚语,另一种是英语。使用 jQuery 按钮将 'active' 类添加到翻译的相应 div(不刷新页面)在页面中激活/提供 2 个翻译。

我正在使用 jQuery 表单验证插件来验证表单。表单验证在罗马尼亚语翻译中工作得非常好(用户登陆页面时的默认视图)。主要问题是当用户点击翻译按钮激活英文版,然后提供表单时,grecaptcha.getResponse() 返回空,导致我的英文表单验证无法提交。

以下是我的代码:

罗马尼亚语形式:

    <form action="forms/contact-form-handler.php" method="POST" UTF-8 id="ro-form">
      <div class="columns is-variable is-2 is-multiline">
        <div class="column is-half">
          <input class="input" type="text" name="name" placeholder="Nume si prenume" id="ro-name">
        </div>
        <div class="column is-half">
          <input class="input" type="email" name="email" placeholder="Email" id="ro-email">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="phone" placeholder="Telefon" id="ro-phone">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="budget" placeholder="Buget">
        </div>
        <div class="column is-full">
          <textarea class="textarea" name="message" placeholder="Message" id="ro-message"></textarea>
        </div>
        <div class="column is-half">
          <div class="g-recaptcha" data-sitekey="my_key_here"></div>
          <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
          <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
        </div>  
      </div>
    </form>

英文形式:

    <form action="forms/contact-form-handler.php" method="POST" UTF-8 id="en-form">
      <div class="columns is-variable is-2 is-multiline">
        <div class="column is-half">
          <input class="input" type="text" name="name" placeholder="Name">
        </div>
        <div class="column is-half">
          <input class="input" type="email" name="email" placeholder="Email" id="en-email">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="phone" placeholder="Phone">
        </div>
        <div class="column is-half">
          <input class="input" type="text" name="budget" placeholder="Budget">
        </div>
        <div class="column is-full">
          <textarea class="textarea" name="message" placeholder="Message"></textarea>
        </div>
        <div class="column is-half">
          <div class="g-recaptcha" data-sitekey="my_key_here"></div>
          <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
          <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
        </div>  
      </div>
    </form>

jQuery 验证实例:

$(function() 
  // Validate Romanian Form
  $("#ro-form").validate(
    ignore: ".ignore",
    rules: 
      name: "required",
      phone: "required",
      email: 
        required: true,
        email: true
      ,hiddenRecaptcha: 
          required: function () 
              if (grecaptcha.getResponse() == '') 
                  return true;
               else 
                  return false;
              
          
      
    ,
    messages: 
      name: "Please enter your name",
      phone: "Please enter your phone number",
      email: "Please enter a valid email address"
    ,
    submitHandler: function(form) 
      form.submit();
    
  );

  // Validate Romanian Form
  $("#en-form").validate(
    ignore: ".ignore",
    rules: 
      name: "required",
      phone: "required",
      email: 
        required: true,
        email: true
      ,hiddenRecaptcha: 
          required: function () 
              if (grecaptcha.getResponse() == '') 
                  return true;
               else 
                  return false;
              
          
      
    ,
    messages: 
      name: "Please enter your name",
      phone: "Please enter your phone number",
      email: "Please enter a valid email address"
    ,

    submitHandler: function(form) 
      form.submit();
    
  );
);

感谢您的帮助。

【问题讨论】:

为什么要使用两种形式??你可以用一个来做到这一点 您在两种表单中都使用与“hiddenRecaptcha”相同的 ID 和名称。它应该是独一无二的。 @daryoshsetorg 因为翻译,我可以使用 1 个表单来完成此操作,但在翻译页面时需要另一个逻辑。 @Devang 嗨,尝试将英文表单上的 id 和 name 更改为唯一,我仍然得到 grecaptcha.getResponse() 的空值。 【参考方案1】:
<form action="forms/contact-form-handler.php" method="POST" UTF-8 id="form">
 <input type="text" class="hidden" id="language" value="1" />
  <div class="columns is-variable is-2 is-multiline">
    <div class="column is-half">
      <input class="input" type="text" name="name" placeholder="Name">
    </div>
    <div class="column is-half">
      <input class="input" type="email" name="email" placeholder="Email" >
    </div>
    <div class="column is-half">
      <input class="input" type="text" name="phone" placeholder="Phone">
    </div>
    <div class="column is-half">
      <input class="input" type="text" name="budget" placeholder="Budget">
    </div>
    <div class="column is-full">
      <textarea class="textarea" name="message" placeholder="Message"></textarea>
    </div>
    <div class="column is-half">
      <div class="g-recaptcha" data-sitekey="my_key_here"></div>
      <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
      <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
    </div>  
  </div>
</form>

如果 value=1 更改,您可以检查具有 id='language' 的输入 占位符为英语 else if value =0 将占位符更改为 罗马尼亚语。

$(function() 
       $("your change button").onClick(()=>
           $("#language").val('0') // or 1
            //write function to change all input to Romanian or English language
            //sample : $('#en-email').attr("placeholder", "Email"); 
         )
     );

【讨论】:

感谢您的回答,但这需要我将 2 个翻译分开放在不同的文件中吗? 2 个翻译位于不同 Div 上的单个 html 文件中。另一个 div 处于活动状态时隐藏,反之亦然,因此使用 1 个表单需要我将它们分开,然后包含表单?我只需要弄清楚为什么 grecaptcha.getResponse() 在第二次翻译处于活动状态时返回空。谢谢。 我认为grecaptcha.getResponse() 只能在您的表单中触发一次您是否多次测试过该触发? 感谢您的最后评论,它指导我搜索如何获取第二个 recaptcha 实例的值。 :)【参考方案2】:

好的,这就是我在收集信息后所做的事情,我偶然发现Gene Kelly 讨论如何使用 grecaptcha.getResponse(0)、grecaptcha.getResponse(2) 等引用每个 recaptcha 实例.所以我搜索了如何创建多个实例并偶然发现turboLoop 的答案,您可以在其中创建带有显式渲染的recaptcha。

这是我的新代码结构:

我在 2 翻译中的新验证码字段

<div class="column is-half">
  <div class="g-recaptcha"></div>
  <input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha">
  <button type="submit" class="button is-warning"><span class="send-btn">Send message</span></button>
</div>

根据 turboLoop 的回答创建渲染的脚本

var CaptchaCallback = function() 
  var captchas = document.getElementsByClassName("g-recaptcha");
  for(var i = 0; i < captchas.length; i++) 
    grecaptcha.render(captchas[i], 'sitekey' : 'my_site_key');
  
;

使用显式渲染加载脚本

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>

jQuery 表单验证插件:

罗马尼亚语div:

...
,hiddenRecaptcha: 
    required: function () 
      if (grecaptcha.getResponse(0) == '') 
        return true;
       else 
        return false;
      
    

...

英文div:

...
,hiddenRecaptcha: 
    required: function () 
      if (grecaptcha.getResponse(1) == '') 
        return true;
       else 
        return false;
      
    

...

所以现在当第二个翻译处于活动状态时,grecaptcha.getResponse() 返回一个值,因为它引用了第二个实例/渲染。

【讨论】:

以上是关于当单个页面上存在 2 个表单时,如何使用 jQuery 表单验证插件验证 reCaptcha?的主要内容,如果未能解决你的问题,请参考以下文章

当单个表单中有多个下拉字段时,如何在 JQuery 中为选择标记引用选择器?

django:csrf_token 用于单个页面上的多个表单和 ajax 请求

如何使用 Angular 2 在单个 ts 文件中编写 2 个表单验证?

当同一页面上有多个使用同一个类时,如何验证电子邮件提交表单?

如何在 Visual Studio 2017 的单个表单上打开多个 OpenGL 窗口?

如何在具有 Ajax 的单个表单中使用多个提交按钮 [关闭]