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
相关产品推荐
相关产品推荐

