1. 场景:
官方商城在订单确认页面(order confirm page),点击确认订单
按钮时,需要走以下代码流程
- ajax 提交数据创建订单
- 如果上一步订单创建成功,跳转到支付通道去支付
2. 问题
但是使用以下几种代码,偶尔(并不是每次)会被浏览器拦截
2.1 ajax 之后,直接用 window.open(url)
略
2.2 ajax 之后,表单提交
示例:
页面放一个 form
<form id="payForm" action="/payment/goToPaymentDirect.htm" target="_blank">
<input type="hidden" name="subOrdinate" id="subOrdinate" value="" />
<input type="hidden" name="payType" id="payType" value="" />
</form>
在ajax 得到结果之后,将相关hidden 附上值,并 提交表单
$('#subOrdinate').val(subOrdinate);
$('#payType').val(payType)
$("#payForm").submit();
2.3 ajax 之后,设置一个 a标签, 然后模拟点击
示例:
页面放了个 空的a
<%-- 自定义提交链接 --%>
<a id="paymentLink" ="" target="_blank" style="display:none"></a>
js 里面 ajax post 提交,拿到支付相关的链接, 通过赋予 a 链接href 属性,模拟click 事件实现
//订单确认
$j("#createOrderButton").click(function(){
var formData=getFormDataToSubmit();
//sConfirm('请您在新打开的页面中完成付款','付款完成前请不要关闭本页面!')
var data = loxia.syncXhrPost(_contextPath+"/transaction/create",formData);
if(null!=data && true==data.result){
var paymentFullRequestURL=data.paymentFullRequestURL;
$j("#paymentLink").attr("href",paymentFullRequestURL);
document.getElementById("paymentLink").click();//$j("#paymentLink").click();//这种方式不行
}
});
以上代码, 曾在 2012年
左右测试是ok的, 这次再使用这招,依然有几率被浏览器拦截
3. 原因
当window.open
为用户触发事件或者加载时
,不会被拦截; 一旦将代码移动到ajax内时,可能就出现被拦截。
Ajax之后打开窗体,浏览器会认为可能是广告弹窗
类的代码
4. 解决方案
在stackoverflow找到了解决方案, 参见 Bypass popup blocker on window.open when JQuery event.preventDefault() is set
4.1 核心思想
先通过用户点击打开一个window,然后再对这个window进行重定向
4.2 流程:
-
在提交
ajax
之前, 先定义一个window
如
var windowObj = window.open();
-
提交
ajax
请求,此请求,需要是async:false
-
如果
ajax
成功, 那么将windowObj
附上新的地址, 如windowObj.location = paymentHref;
-
如果
ajax
失败或者异常, 那么需要将windowObj
关闭, 如windowObj.close();
4.3 示例代码:
$('#createOrder').on('tap',function(){
var windowObj = window.open(); //在提交 `ajax` 之前, 先定义一个 `window`
$.ajax({
type: 'POST',
url: base + '/transaction/create',
dataType: 'json',
async:false, //注意是 async:false
success: function(result){
var subOrdinate = result.returnObject.subOrdinate;
var payType=$('input[name="paymentInfoSubForm.paymentType"]').val();
var paymentHref=base+"/payment/goToPaymentDirect.htm?subOrdinate="+subOrdinate+"&payType="+payType;
windowObj.location = paymentHref;
//do something else
//比如 弹出友好型提示层
},
error: function(){
//如果提交失败, 或者校验有问题, 这里需要关闭 打开的window
windowObj.close();
}
});
});