微信内置安卓x5浏览器请求超时自动重发问题处理小记
X5内核 请求超时后会自动阻止请求返回并由代理服务器将原参数重新发送请求到服务层代码。但由于第一次请求已经请求到服务器,会导致出现重复下单、支付等重大问题。
该问题由于腾讯x5浏览器会自动阻止第一次请求返回到页面,届时将抛出io异常。最开始打算通过拦截器来进行拦截第二次请求,但这样将使页面无法接受到返回信息报错。
初步解决思路 当第二次请求访问进服务层时暂停该线程,并定时循环查询第一次请求是否返回成功,将第一次返回成功的结果赋值给第二次。
由于我们系统中所有页面请求都会过一个通用controller 所以也会有很多正常请求通过 为了不影响整体使用
这里我用到了页面验签的方法,用于验证请求是否为同一次。这里先将参数进行排序,再用md5加密,添加一个“sign”的参数到后台,后台再排序加密进行比对,进行验签,注意这里参数加入了
时间戳,用于防止重复提交
KGF.getMD5 = function(params){
params["key"] = "ouE6yWvy";
var sParams = Object.keys(params).sort();
var oriString = "";
for(key in sParams){
oriString += sParams[key]+"="+params[sParams[key]]+"&";
}
oriString = oriString.substr(0,oriString.length-1);
delete params.key;
return KGF.md5(oriString);
};
验签成功后,由于需要将第一次返回成功的结果赋值给第二次。所以需要将调用接口成功的结果存入seesion中,但此时需要及时去清理,否则容易造成服务器内存溢出。
默认调用接口成功后就将结果集放入session,验签一通过就去取,这里的关键在于何时去删除session中的值。由于所有结果访问均会通过该控制器,为了区分不同的请求,
故用sign作为键,返回结果为值。
下面贴出代码
@RequestMapping(value={"/common/ajax.do"}, method={RequestMethod.POST}, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public List<AjaxResponse> execute2(@RequestHeader(value="Accept", required=false) String accept, HttpServletRequest request){
XMLResults results = new XMLResults();
try{
AjaxObject object = (AjaxObject)request.getAttribute("ParamName");
String openid = (String) request.getSession().getAttribute("openid");
Class[] cArg = new Class[2];
cArg[0] = HttpServletRequest.class;
cArg[1] = Map.class;
DataResult dataResult = new DataResult();
Map<String, Object> params = object.getParams();
String signFromAjax = (String) params.get("sign");
long startTime = 0;
long endTime = 0;
if(!checkSign(params)){
log.error("接口请求验签失败");
dataResult.setRetInfo("-1", "接口请求验签失败", CommonUtil.parseDoubleList(new HashMap()));
}else{
String signFromSession = (String) request.getSession().getAttribute(signFromAjax);
request.getSession().setAttribute(signFromAjax,signFromAjax);
//处理腾讯安卓微信浏览器,10s重发请求的问题
if(signFromSession != null){
for(int i = 0; i <10; i++){
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("====================重复请求读取接口返回信息:第"+(i+1)+"次====================");
DataResult dataResultFromSession = (DataResult) request.getSession().getAttribute(signFromAjax+"interfaceResult");
if(dataResultFromSession != null){
request.getSession().removeAttribute(signFromAjax);
request.getSession().removeAttribute(signFromAjax+"interfaceResult");
results = this.baseService.convertResult(dataResult);
dataResult = dataResultFromSession;
break;
}
if(i == 9){
dataResult.setRetInfo("-1", "接口请求超时,请联系管理员", CommonUtil.parseDoubleList(new HashMap()));
}
}
}else{
startTime = new Date().getTime();
params.put("requestIp", CommonUtil.getIpAddr(request));
params.put("openid", openid);
params.put("deviceType", CommonUtil.getDeviceType(request));
params.put("browserType", CommonUtil.getBrowserType(request));
params.put("g_stationaddr", CommonUtil.getIpAddr(request));
Method method = commonDataModel.getClass().getDeclaredMethod(object.getCode(), cArg);
dataResult = (DataResult) method.invoke(commonDataModel, request, params);
endTime = new Date().getTime();
request.getSession().setAttribute(signFromAjax+"interfaceResult", dataResult);
}
}
if(endTime - startTime <= 10000){
request.getSession().removeAttribute(signFromAjax);
request.getSession().removeAttribute(signFromAjax+"interfaceResult");
}
results = this.baseService.convertResult(dataResult);
}catch (Exception e){
log.error("数据请求失败,错误信息:" + e.getMessage());
results.setRetInfo("-1", "数据请求失败");
}
return webHelper.convertAjaxResponse(results);
}
微信内置安卓x5浏览器请求超时自动重发问题处理小记的更多相关文章
- 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题
前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...
- 让微信内置浏览器兼容clipboard.js 复制粘贴 ios 安卓
<!--js copy事件--><script type="text/javascript" src="/static/js/clipboard.min ...
- 微信内置浏览器http请求10秒内接收不到数据会自动重发第二遍请求
微信内置浏览器http请求10秒内接收不到数据会自动重发第二遍请求 这是个坑
- asp.net微信内置浏览器下Session失效
问题记录:仅限安卓端微信内置浏览器,服务器集群设置了黏性Session,在Post请求时会强制走代理,导致出去的ip指向另一台服务器,黏性Session失效,用户状态无法保存. 目前想知道除了设置Se ...
- 微信内置浏览器WebApp开发,踩坑 · Issue #31 · maxzhang/maxzhang.github.com · GitHub
最近花6天时间完成了一个七夕的小活动,是一个简单的WebApp.由于我前期对面向微信的Web开发评估不足,导致开发过程十分艰难.写这篇文章总结下,惊醒自己未来不要再犯这样的错误. 问题: 1. 有些比 ...
- 微信内置浏览器的JsAPI(WeixinJSBridge续)[转载]
原文地址: http://www.baidufe.com/item/f07a3be0b23b4c9606bb.html 之前有写过几篇关于微信内置浏览器(WebView)中特有的Javascript ...
- 【微网站开发】之微信内置浏览器API使用
最近在写微网站,发现了微信内置浏览器的很多不称心的地方: 1.安卓版的微信内浏览器底部总是出现一个刷新.前进.后退的底部栏,宽度很大,导致屏幕显示尺寸被压缩 2.分享当前网站至朋友圈时,分享的图片一般 ...
- 微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone)
微信内置浏览器中,点击下拉框出现页面乱跳转现象(iphone) 前言: 这是小菜博客的第三篇文章.一直认为自己可以表达的东西太过简单,难以上台面,总是吝啬地不肯写.就算是写,也不知道从何开始.在同事的 ...
- 微信内置浏览器的JsAPI(WeixinJSBridge续)_Alien的笔记
微信内置浏览器的JsAPI(WeixinJSBridge续)_Alien的笔记 微信内置浏览器的JsAPI(WeixinJSBridge续)进入全屏 之前有写过几篇关于微信内置浏览器(WebView) ...
随机推荐
- 图像的下采样Subsampling 与 上采样 Upsampling
I.目的 缩小图像(或称为下采样(subsampled)或降采样(downsampled))的主要目的: 1.使得图像符合显示区域的大小: 2.生成对应图像的缩略图. 放大图像(或称为上采样(ups ...
- Jquery实现轮播公告
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python sqlite3操作笔记
创建数据库 def create_tables(dbname): conn = sqlite3.connect(dbname) print "Opened database successf ...
- RecyclerView+SwpieRefreshLayout(转载)
开源库BaseRecyclerViewAdapterHelperhttp://blog.csdn.net/xiangzhihong8/article/details/52138669http://ww ...
- 从0移植uboot(六) _实现网络功能
为uboot添加网卡功能可以让uboot通过tftp下载内核, 方便我们的开发, 对于网卡功能的移植,我们依然在在一遍又一遍的实践这个uboot改造的套路. 找运行逻辑,即插入代码的位置. 根据运行逻 ...
- Ubuntu 18.04 Numix主题安装设置
Ubuntu 18.04 Numix主题安装设置 一.首先安装Numix主题 展现效果如下图 1.安装numix sudo add-apt-repository ppa:numix/ppa 2.安装主 ...
- highcharts.js的时间轴折线图
工作中正好用到. 鼠标按住左键 左右移动可以试试 <!DOCTYPE> <html lang='en'> <head> <title>4-Highcha ...
- 全局解释器锁GIL
我们使用高并发,一次是创建1万个线程去修改一个数并打印结果看现象: from threading import Thread import os def func(args): global n n ...
- Nest.js WebSocket
Docs: https://docs.nestjs.com/websockets/gateways λ yarn add @nestjs/websockets λ nest g ga events e ...
- [ACM-ICPC 2018 徐州赛区网络预赛][D. Easy Math]
题目链接:Easy Math 题目大意:给定\(n(1\leqslant n\leqslant 10^{12}),m(1\leqslant m\leqslant 2*10^{9})\),求\(\sum ...