方案原因:防止fiddler抓包时修改参数,在ajax发送前统一拦截ajax,获取参数,加密之后放到header中,后台编写一个过滤器filter,所有请求都经过过滤器,取出参数,拼接加密,取出header,比对成功就说明没有被修改,不一样则表示被修改了
ajax发送前拦截
/**
* 在ajax发送之前添加加密参数
*/
$(document).ajaxSend(function(event,xhr,options){
//判断是否有MD5加密的js文件,没有则添加上
if($("script[src='/js/jQuery.md5.js']").length <= 0){
$("head").append('<script src="/js/jQuery.md5.js"></script>');
}
var url=options.url;
var data=options["data"];
//获取url?之后拼接的参数
var allArray=[];
var urlArray=[];
var dataArray=[]
if(url.indexOf("?")>-1){
var urlDataStr=url.slice(url.lastIndexOf("?")+1,url.length);
urlArray=urlDataStr.split("&");
}
//获取data参数
if(data){
dataArray=data.split("&");
}
//将拼接的参数和data参数拼接起来
allArray=urlArray.concat(dataArray);
//记录key和对应的位置
var keyJson={};
//如果有相同key的时候,在数组中移除
for (var i = 0; i < allArray.length; i++) {
var key=allArray[i].split("=")[0];
var value=allArray[i].split("=")[1];
//如果数组中key有相同的时候,删除这个数组 且value不为空
if (!keyJson.hasOwnProperty(key) && value!=null && ""!=value+""){
keyJson[key]="";
}else{
allArray.splice(i,1);
i--;
}
}
//将数组按首字母排序
allArray.sort();
//遍历数组
var dataMap={};
var comparison="";
//拼接value
for (var i = 0; i < allArray.length; i++) {
var dataSplit=allArray[i].split("=");
var value=dataSplit[1];
comparison+=value;
}
//中文转译解码 及空格加号编码和解码的问题
comparison=decodeURIComponent(comparison.replace(/\+/g, '%20'));
xhr.setRequestHeader("comparison",$.md5(comparison));
});
filter方法
// 获取请求头comparison
String comparison = request.getHeader("comparison");
// 将key取出来放到list集合中
List<String> paramKeyList = new ArrayList();
//paramMap是获取的request的参数
Iterator iterator = paramMap.keySet().iterator();
// 将key按首字母排序
while (iterator.hasNext()) {
paramKeyList.add((String) iterator.next());
}
Collections.sort(paramKeyList);
StringBuffer paramValueStr = new StringBuffer();
// 取出value进行拼接 如果value不为空的情况下
for (String key : paramKeyList) {
String[] value = (String[]) paramMap.get(key);
if (value[0] != null && !"".equals(value[0])) {
paramValueStr.append(value[0]);
}
}
// md5加密(这是自己封装的MD5加密方法)
String encryptString = EncryptTool.EncryptString(paramValueStr.toString().trim());
// 获取
// 比对,如果和前台不一样,直接返回
if (!comparison.equals(encryptString)) {
return;
}
注意事项
decodeURIComponent(comparison.replace(/\+/g, '%20'));
1.方法拦截前已经对参数编码了,所以调用decodeURIComponent对方法解码
2.由于两种协议不同的原因,replace(/+/g, ‘%20’),把所有加号换成’%20’,具体请见:URL中关于空格的编码