Stripe支付后Javascript表单提交在Safari失效,其他浏览器正常
Stripe支付后表单提交在Safari中失效的解决方案
问题场景
基于Stripe支付网关开发的功能,支付成功后通过AJAX回调提交表单以跳转创建订单,该功能在Chrome、Firefox中正常,但部分场景下Safari中失效,核心问题是AJAX成功回调内的document.getElementsByName("stripe_form")[0].submit()无法触发表单提交。
可能原因
- Safari安全策略限制:Safari对非用户直接交互触发的表单提交有严格限制,AJAX异步回调属于脱离用户交互上下文的操作,会被浏览器阻止
submit()调用。 - alert阻塞执行:
alert()会暂停JavaScript执行流程,在Safari中可能破坏后续表单提交的上下文,导致提交动作失效。 - 表单元素获取不稳定:
document.getElementsByName()返回HTMLCollection,某些场景下可能无法准确获取目标表单。
解决方案
1. 替换alert为非阻塞式提示
移除alert(),改用DOM元素显示提示,避免阻塞JS执行流程:
// 创建临时提示元素 const successNotice = document.createElement('div'); successNotice.textContent = "Payment done, now order will create"; successNotice.style.cssText = "padding:10px; background:#d4edda; color:#155724; position:fixed; top:20px; left:50%; transform:translateX(-50%); z-index:9999;"; document.body.appendChild(successNotice); // 2秒后自动移除提示 setTimeout(() => successNotice.remove(), 2000);
2. 模拟用户交互触发表单提交
通过模拟点击表单的提交按钮(或创建隐藏提交按钮)来触发表单提交,这种方式符合Safari的交互上下文要求:
// 稳定获取表单元素 const stripeForm = document.querySelector('form[name="stripe_form"]'); if (!stripeForm) { console.error('目标表单未找到'); return; } // 尝试获取已有提交按钮 const submitButton = stripeForm.querySelector('button[type="submit"], input[type="submit"]'); if (submitButton) { // 模拟点击提交按钮 submitButton.click(); } else { // 若没有提交按钮,创建隐藏按钮并模拟点击 const hiddenSubmit = document.createElement('button'); hiddenSubmit.type = 'submit'; hiddenSubmit.style.display = 'none'; stripeForm.appendChild(hiddenSubmit); hiddenSubmit.click(); hiddenSubmit.remove(); }
3. 优化表单元素获取逻辑
用document.querySelector()替代document.getElementsByName(),更稳定且语义明确:
// 替代原有的document.getElementsByName("stripe_form")[0] const stripeForm = document.querySelector('form[name="stripe_form"]');
修改后的完整代码片段
function handleServerResponse(response) { if (response.error) { // Show error from server on payment form if(response.payment_intent_id !== undefined){ $.ajax({ type: "POST", url: "stripe_response_save.php", data: "id="+response.payment_intent_id, cache: false, success: function(r){ const form3 = document.querySelector('#form3'); // 假设form3有id,无id则替换为对应选择器 if(form3) form3.submit(); } }); } alert(response.error); setLoading(false); } else if (response.requires_action) { // Use Stripe.js to handle required card action stripe.handleCardAction( response.payment_intent_client_secret ).then(handleStripeJsResult); } else { // Show success message $("#pmtint_id").val(response.payment_intent_id); const stripeForm = document.querySelector('form[name="stripe_form"]'); if (!stripeForm) { console.error('Stripe form not found'); return; } $.ajax({ type: "POST", url: "stripe_response_save.php", data: "id="+response.payment_intent_id, cache: false }).done(function(r){ // 非阻塞式提示 const successNotice = document.createElement('div'); successNotice.textContent = "Payment done, now order will create"; successNotice.style.cssText = "padding:10px; background:#d4edda; color:#155724; position:fixed; top:20px; left:50%; transform:translateX(-50%); z-index:9999;"; document.body.appendChild(successNotice); setTimeout(() => successNotice.remove(), 2000); // 模拟提交按钮点击 const submitButton = stripeForm.querySelector('button[type="submit"], input[type="submit"]'); if (submitButton) { submitButton.click(); } else { const hiddenSubmit = document.createElement('button'); hiddenSubmit.type = 'submit'; hiddenSubmit.style.display = 'none'; stripeForm.appendChild(hiddenSubmit); hiddenSubmit.click(); hiddenSubmit.remove(); } }) return false; } }
内容的提问来源于stack exchange,提问作者Ayan Biswas
相关产品推荐
相关产品推荐

