要知道,在浩瀚的互联网中,所有的信息都是不安全的,万一有人偷窥我们怎么办?!万一被别人看见了我们的美体,偷窥到了我们的私处,然后以此威胁我们,岂不是太难堪了不是?这时,你或许会想给请求数据和响应数据加密,就相当于给我们的数据穿上了一层衣服。于是我们这样:
是不是美美哒,对,穿上一层漂漂亮亮的衣服,就不怕别人偷窥我们的美体了,我们出门的时候要穿衣服,回家的时候也要脱衣服,也就是说ajax请求的参数需要加密,ajax响应的数据的要解密,如果说项目只有几个ajax请求需要加密的话还OK,发请求之前把data处理一遍,success回调函数把responseText解密一遍就完了。可是倘若架构大一点,ajax请求多一点,每次请求响应都要单独处理加密解密启不是太冗余了,于是我便去翻阅jQuery ajax参考手册,还真的有不小的收获。
首先jQuery有一个 ajaxSetup 方法,该方法可以设置全局 ajax 初始化参数,也就是说在声明了该方法之后的所有 ajax 请求都会默认使用该方法设置的初始值。
然后我们再翻阅 ajax 参数,突然,我眼前一亮!有一个叫做 beforeSend 的方法,我一看这名字就亮了!这个函数也就是在发送 ajax 请求之前的回调函数,于是我们先把它用起来:
$.ajaxSetup({ beforeSend: function() {console.log(arguments);//我们先来看看这里面有什么好玩的东西} });然后我们在随便发一个 ajax 请求:
$.ajax({url: "SetupServlet",type: "GET",data: { param1: "test1", param2: "test2",} });在控制台我们可以看见打印的参数列表有两个对象,我们先来看看 W3C 里对 beforeSend 的解释:
看到这里我们大致明白了,我们这个对象大致就是 ajax 的参数对象,由于我们本次实验的目的是给我们将要在互联网中遨游的数据穿衣服,那么我们看看这个衣服该穿在哪呢?在这个对象的 url 我们可以看到,jQuery 的 ajax 操作已经我们之前传进来的参数序列化并附加在了 url 后面,因为这是 GET 请求。那么 POST 请求长什么样呢?我们再来试一下:
$.ajax({url: "SetupServlet",type: "POST",data: { param1: "test1", param2: "test2", },});现在这个参数对象长这个样子:
我们可以看到不同之处在于 POST 请求多了一个 data 属性,并且 url 后面没有参数序列化字符串,但是 data 属性却是序列化之后的参数字符串。至此我们已经可以在 beforeSend 函数中对请求前的参数进行修改了,GET 请求修改 url 后面的参数,POST 请求修改 data 中的值,具体效果在这里暂时不演示。
但是到这里我依旧不是很爽啊,因为无论是 GET 还是 POST 的,我得到的都是序列化之后的字符串,要修改参数的话得先反序列化,然后才能处理,于是我又在 ajax API 当中寻找,功夫不负有心人,我找到了一个叫做 processData 的东西,先来看看官方解释:
$.ajaxSetup({ beforeSend: function() { console.log(arguments); }, processData: false, });这时请求中的参数会发生如下变化
POST:
这里我只截取部分截图,我们看到我们传进来的参数在 POST 请求就是原生的对象,终于得到我想要的东西了,此时此刻我心中大喜!必须得抽根烟祝祝性,额不对...是祝祝兴。于是我们可以拿这个 data 尽情的蹂躏,随意的鞭打,我要把这个 data 对象尽情的践踏!额,不好意思有点激动。回到正题,我们要给 data 穿衣服才对嘛,怎么说着说着就要开始脱衣服了...好的,下面我们开始穿衣服,在这里我以 base64 举例,我对请求的参数进行 base64 编码:
$.ajaxSetup({beforeSend: function() {console.log(arguments);var params = arguments[1].data;var data = "";for (var key in params) {//这两行代码的意思是进行 base64 编码var dataUtf8 = CryptoJS.enc.Utf8.parse(params[key]);var dataBase64 = CryptoJS.enc.Base64.stringify(dataUtf8);data = data.concat("&" + key + "=" + dataBase64);};arguments[1].data = data.substring(1, data.length);//将序列化后的参数重写},processData: false,});于是乎,我们的请求参数就穿上了一身漂漂亮亮的衣服遨游在互联网的世界里了,因为 jquery 在 GET 方法中会自动把 data 附加在 url 后面,所以将 processData 设置为 false 之后 url 后面会出现 [object object] ,这是 javascript 对象 toString() 过后的结果,也就是说我们的这个方法并不很适合 GET 方法,所以想给数据穿衣服的同学们还是乖乖的使用 POST 方法吧。
$.ajaxSetup({beforeSend: function() {console.log(arguments);var params = arguments[1].data;var data = "";for (var key in params) {//这两行代码的意思是进行 base64 编码var dataUtf8 = CryptoJS.enc.Utf8.parse(params[key]);var dataBase64 = CryptoJS.enc.Base64.stringify(dataUtf8);data = data.concat("&" + key + "=" + dataBase64);};arguments[1].data = data.substring(1, data.length);//将序列化后的参数重写},processData: false,dataFilter: function() {console.log(arguments);//这是我的一个习惯,拿到一个函数之后,管他是什么东西,先看看里面有什么参数return "world";}});$.ajax({url: "SetupServlet",type: "POST",dataType: "text",data: {param1: "test1",param2: "test2",},success: function(responseText) {console.log(responseText);},});后台代码(java):
String param1 = request.getParameter("param1"); String param2 = request.getParameter("param2"); System.out.println("param1: " + param1); System.out.println("param2: " + param2); response.getWriter().write("hello");后端输出:
前端输出:
看来一切正常,现在我们加密和解密的过程进行一条龙的处理:
前端:
$.ajaxSetup({beforeSend: function () {var params = arguments[1].data;var data = "";for (var key in params) {var dataUtf8 = CryptoJS.enc.Utf8.parse(params[key]);var dataBase64 = CryptoJS.enc.Base64.stringify(dataUtf8);data = data.concat("&" + key + "=" + dataBase64);};arguments[1].data = data.substring(1, data.length);},processData: false,dataFilter: function () {var result = "";try {var a = CryptoJS.enc.Base64.parse(arguments[0]);var result = CryptoJS.enc.Utf8.stringify(a);} catch(e) {result = arguments[0];} finally {return result;}}});后台:
String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");byte[] buffer1 = Base64.decodeBase64(param1);byte[] buffer2 = Base64.decodeBase64(param2);System.out.println("param1: " + new String(buffer1));System.out.println("param2: " + new String(buffer2));response.getWriter().write(Base64.encodeBase64String("hello".getBytes()));后台输出:
前端输出:
至此已经大功告成了,让我们来总结下我们使用过的东西
第一个: ajaxSetup 这是设置全局的初始属性
然后是三个属性:
beforeSend:发送前执行的函数
processData:默认不序列化参数
dataFilter:对响应的数据进行过滤
然后,我们就可以给我们的数据穿上一层漂漂亮亮的衣服了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!