与ajax同步不可见recapcha

问题描述

所以我试图弄清楚如何从Recaptcha获取令牌或有效响应,然后运行ajax调用。有人知道我该如何同步吗?

用户单击“提交”时,过程将是:

  1. 能够通过必需的属性和模式来验证表单字段
  2. 获取Recaptcha令牌或响应
  3. 如果Recaptcha响应良好,请运行Ajax
function onSubmit(token) {

  grecaptcha.execute()
  var response = grecaptcha.getResponse();
  return response.length;
}

$('#contact-form').submit(function(event) {
  event.preventDefault();


  if (onSubmit()) {

    jQuery.ajax({
      url: "/ipostal-office/send-email.PHP",data: $('#contact-form').serialize(),type: "POST",complete: function(data) {
        console.log(data.responseText);
      },success: function(data) {
        // console.log(data);
        $('#contact-form').fadeOut();
        $('#success').fadeIn();
      },error: function(data) {
        console.log(data.responseText);
        $('#error').fadeIn();
        $('#contact-form').fadeOut();
      }
    });

  }
});
#form-div {
  border-radius: 4px;
  border: 1px solid #e8e8e8;
  padding: 1rem 1rem 1.5rem 1rem;
}

#form-div .hide {
  display: none;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

<div id="form-div">

  <h2>Contact Us to Learn More</h2>

  <div id="success" class="hide">
    <p>Your message was sent successfully! </p>
  </div>

  <div id="error" class="hide">
    <p>Something went wrong,<br> try refreshing and submitting the form again.</p>
  </div>

  <form id="contact-form" action="send-email.PHP" method="post">

    <div class="input-field-div">
      <input type="text" id="name" name="name" placeholder=" " minlength='2' pattern="^[a-zA-Z ]*$" title="Only letters and white space allowed" required>
      <label for="name">Name*</label>
    </div>

    <div class="input-field-div">
      <input type="text" id="title" name="title" placeholder=" ">
      <label for="title">Title</label>
    </div>

    <div class="input-field-div">
      <input type="text" id="company" name="company" minlength='2' placeholder=" " required>
      <label for="company">Company*</label>
    </div>

    <div class="input-field-div">
      <input type="text" id="address" name="address" placeholder=" ">
      <label for="address">Address</label>
    </div>

    <div class="input-field-div">
      <input type="email" id="email" name="email" placeholder=" " required>
      <label for="email">Email*</label>
    </div>

    <div class="input-field-div">
      <input type="tel" id="phone" name="phone" placeholder=" ">
      <label for="phone">Phone</label>
    </div>

    <div class="message-field-div">
      <textarea name="message" id="message" rows="7" placeholder=" " minlength='2' required></textarea>
      <label for="message">Message</label>
    </div>

    <div id='recaptcha' class="g-recaptcha" data-sitekey="6LebLMwZAAAAAEGMbnSYotyk9do2paxL97t0-6C8" data-callback="onSubmit" data-size="invisible"></div>

    <button id="submit-btn" type="submit">
                        Submit <i class="fas fa-paper-plane"></i>
                    </button>

  </form>

</div>

解决方法

如果您以public static addDelayedFunction<T>(delayedFunction: Function,delay_ms: number): (mainObs: Observable<T>) => Observable<T> { const stopTimer$: Subject<void> = new Subject<void>(); const stopTimer = (): void => { stopTimer$.next(); stopTimer$.complete(); }; const catchErrorAndStopTimer = (obs: Observable<T>): Observable<T> => { return obs.pipe(catchError(err => { stopTimer(); throw err; })); }; const timerObs: Observable<any> = of({}) .pipe(delay(delay_ms)) .pipe(takeUntil(stopTimer$)) .pipe(tap(() => delayedFunction())); return (mainObs: Observable<T>) => catchErrorAndStopTimer( of({}) .pipe(tap(() => timerObs.subscribe())) .pipe(mergeMap(() => catchErrorAndStopTimer(mainObs.pipe(tap(stopTimer))))) ); } 事件处理程序的形式调用grecaptcha.execute(),并将AJAX调用移至submit函数,则此方法应该有效。

表单提交处理程序将阻止实际的提交并启动异步reCAPTCHA。当reCAPTCHA响应可用时,它将在表单中插入一个隐藏的输入字段并调用onSubmit。

onSubmit
function onSubmit(token) {
  //Submit via AJAX
  alert($('#contact-form').serialize());
}

$('form').submit(function(e) {
  event.preventDefault();
  grecaptcha.execute();
});

请注意,由于来源无效,该示例在此处嵌入时无法正常工作。