You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify中如何通过AJAX提交带Captcha Token的找回密码表单

Shopify找回密码表单AJAX提交集成Captcha Token解决方案

当启用Shopify后台的垃圾信息保护后,需要通过官方Captcha API处理验证,才能让AJAX提交正常工作。以下是针对你现有代码的调整方案:

关键修改点

  • 增加window.Shopify.captcha存在性检查,避免抽屉菜单动态加载时脚本未就绪报错
  • 完善Captcha验证失败的处理逻辑
  • 优化响应错误判断,区分表单验证错误和Captcha验证错误
  • 确保Captcha验证通过后,Token自动注入表单数据

修改后的完整代码

{%- form 'recover_customer_password', id:"RecoverPasswordForm" -%}
  {%- assign recover_success = form.posted_successfully? -%}
  {%- if form.errors -%}
    <div class="form-notification error" id="RecoverEmail-email-error">
      {% render 'svg-icons' with 'thb-error' %} {{ form.errors.messages['form'] }}
    </div>
  {%- endif -%}
  <div class="field">
    <input type="email"
      value=""
      name="email"
      id="RecoverEmail"
      autocorrect="off"
      autocapitalize="off"
      autocomplete="email"
      placeholder="{{ 'customer.login_page.email' | t | escape }}"
      {% if form.errors %}
        aria-invalid="true"
        aria-describedby="RecoverEmail-email-error"
        autofocus
      {% endif %}
      class="full"
      placeholder="{{ 'customer.login_page.email' | t }}"
    >
  </div>
  <button type="submit" class="button full"><span>{{ 'customer.login_page.submit' | t | escape }}</span></button>
  <div class="switch-login-section">
    <a href="#login" class="text-button">
      {{ 'customer.login_page.cancel' | t }}
    </a>
  </div>
{%- endform -%}

<script>
document.addEventListener("DOMContentLoaded", function () {
  const form = document.getElementById("RecoverPasswordForm");

  if (!form) return;

  form.addEventListener("submit", function (e) {
    e.preventDefault();
    clearMessages();

    // 检查Shopify Captcha脚本是否加载完成
    if (!window.Shopify?.captcha) {
      showError("验证服务未就绪,请稍后重试");
      return;
    }

    // 触发Captcha验证,验证通过后执行提交逻辑
    window.Shopify.captcha.protect(
      form,
      () => {
        const formData = new FormData(form);

        fetch(form.action, {
          method: "POST",
          headers: {
            "Accept": "application/json"
          },
          body: formData
        })
        .then((response) => {
          if (response.ok) {
            return response.json().catch(() => ({}));
          } else if (response.status === 422) {
            // 422状态码对应表单验证失败(包含Captcha错误)
            return response.json();
          } else {
            throw new Error("网络请求失败");
          }
        })
        .then((data) => {
          if (data.errors?.captcha) {
            showError("验证失败,请重新完成验证");
          } else if (data.status === 422 || data.form || data.errors) {
            console.error("表单验证失败", data);
            showError(form.errors?.messages?.form || "请检查邮箱格式后重试");
          } else {
            showSuccess("如果该邮箱在我们的系统中,你将很快收到密码重置邮件");
            // 提交成功后清空输入框
            document.getElementById("RecoverEmail").value = "";
          }
        })
        .catch((err) => {
          console.error(err);
          showError("提交失败,请稍后重试");
        });
      },
      // Captcha验证失败的回调(比如用户关闭验证弹窗)
      () => {
        showError("请完成验证后提交");
      }
    );
  });

  function clearMessages() {
    const oldMessages = form.querySelectorAll(".form-success, .form-error, .form-notification");
    oldMessages.forEach((el) => el.remove());
  }

  function showSuccess(message) {
    clearMessages();
    const msg = document.createElement("p");
    msg.className = "form-success";
    msg.innerText = message;
    form.prepend(msg);
  }

  function showError(message) {
    clearMessages();
    const msg = document.createElement("div");
    msg.className = "form-notification error";
    msg.innerHTML = `{% render 'svg-icons' with 'thb-error' %} ${message}`;
    form.prepend(msg);
  }
});
</script>

额外注意事项

  • 确保Shopify后台已启用垃圾信息保护(路径:设置 -> 商店设置 -> 客户账户 -> 垃圾信息保护)
  • 如果侧边栏抽屉是动态加载的(点击后才渲染表单),需在抽屉渲染完成后重新初始化表单的提交事件监听
  • 测试时关闭浏览器广告拦截插件,避免Captcha脚本被拦截

内容的提问来源于stack exchange,提问作者Praveshji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:59:51