用jQuery.ajaxSetup实现对请求和响应数据的过滤


Posted in Javascript onDecember 20, 2016

不知道同学们在做项目的过程中有没有相同的经历呢?在使用 ajax 的时候,需要对请求参数和响应数据进行过滤处理,比如你们觉得就让请求参数和响应信息就这么赤裸裸的在互联网里来回的穿梭,比如这样:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

要知道,在浩瀚的互联网中,所有的信息都是不安全的,万一有人偷窥我们怎么办?!万一被别人看见了我们的美体,偷窥到了我们的私处,然后以此威胁我们,岂不是太难堪了不是?这时,你或许会想给请求数据和响应数据加密,就相当于给我们的数据穿上了一层衣服。于是我们这样:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

是不是美美哒,对,穿上一层漂漂亮亮的衣服,就不怕别人偷窥我们的美体了,我们出门的时候要穿衣服,回家的时候也要脱衣服,也就是说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 的解释:

  • beforeSend(XHR)
  • 类型:Function
  • 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。
  • XMLHttpRequest 对象是唯一的参数。
  • 这是一个 Ajax 事件。如果返回 false 可以取消本次 ajax 请求。

实际上这里是不对的,因为XHR不是唯一的参数,XHR只是 arguments[0] ,我们还有一个 arguments[1],我们来看看这是什么东西:

以下是在 Firefox Developer Edition(Firefox 的开发者版本,最近发现的,绝得超好用) 中打印的东西:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

看到这里我们大致明白了,我们这个对象大致就是 ajax 的参数对象,由于我们本次实验的目的是给我们将要在互联网中遨游的数据穿衣服,那么我们看看这个衣服该穿在哪呢?在这个对象的 url 我们可以看到,jQuery 的 ajax 操作已经我们之前传进来的参数序列化并附加在了 url 后面,因为这是 GET 请求。那么 POST 请求长什么样呢?我们再来试一下:

$.ajax({
  url: 'SetupServlet',
  type: 'POST',
  data: {
   param1: 'test1',
   param2: 'test2',
   },
 });

现在这个参数对象长这个样子:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

我们可以看到不同之处在于 POST 请求多了一个 data 属性,并且 url 后面没有参数序列化字符串,但是 data 属性却是序列化之后的参数字符串。至此我们已经可以在 beforeSend 函数中对请求前的参数进行修改了,GET 请求修改 url 后面的参数,POST 请求修改 data 中的值,具体效果在这里暂时不演示。

但是到这里我依旧不是很爽啊,因为无论是 GET 还是 POST 的,我得到的都是序列化之后的字符串,要修改参数的话得先反序列化,然后才能处理,于是我又在 ajax API 当中寻找,功夫不负有心人,我找到了一个叫做 processData 的东西,先来看看官方解释:

  • processData
  • 类型:Boolean
  • 默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。

也就是说默认情况下 jQuery 会自动帮我们把参数序列化,那么我们现在把它设置为 false 看看会发生什么:

$.ajaxSetup({
    beforeSend: function() {
     console.log(arguments);
    },
    processData: false,   
   });

这时请求中的参数会发生如下变化

GET:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

POST:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

这里我只截取部分截图,我们看到我们传进来的参数在 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 方法吧。

讲到这里,发送数据我们解决了,但是接受数据呢?如果接受的数据也是进行加密的话,我们还需要对数据进行解密(说到这里还是得脱衣服[捂脸]),我们继续翻阅 API ,于是我又看到了一个叫做 dataFilter 的东西,老规矩,先看官方解释:

  • dataFilter
  • 类型:Function
  • 给 Ajax 返回的原始数据的进行预处理的函数。提供 data 和 type 两个参数:data 是 Ajax 返回的原始数据,type 是调用 jQuery.ajax 时提供的 dataType 参数。函数返回的值将由 jQuery 进一步处理。

该函数很简单,就两个参数,arguments[0] 是 ajax 的原始响应数据,也就是 XHR.responseText ,arguments[1] 是 ajax 请求参数中的 dataType ,而这个函数返回的值也就是 success 回调函数中的 responseText,这下就非常好办了,我们先来测试下:

前端代码发送 ajax 请求,后台响应一句 "hello" ,然后我们在 dataFilter 里返回一句 "world"

前端代码:

$.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");

后端输出:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

前端输出:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

看来一切正常,现在我们加密和解密的过程进行一条龙的处理:

前端:

$.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()));

后台输出:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

前端输出:

用jQuery.ajaxSetup实现对请求和响应数据的过滤

至此已经大功告成了,让我们来总结下我们使用过的东西

第一个: ajaxSetup 这是设置全局的初始属性

然后是三个属性:

beforeSend:发送前执行的函数

processData:默认不序列化参数

dataFilter:对响应的数据进行过滤

然后,我们就可以给我们的数据穿上一层漂漂亮亮的衣服了。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
一个高效的JavaScript压缩工具下载集合
Mar 06 Javascript
jQuery 性能优化指南(3)
May 21 Javascript
javascript字符串拼接的效率问题
Dec 25 Javascript
jQuery代码优化之基本事件
Nov 01 Javascript
鼠标经过显示二级菜单js特效
Aug 13 Javascript
用unescape反编码得出汉字示例
Apr 24 Javascript
js运动应用实例解析
Dec 28 Javascript
详解JS对象封装的常用方式
Dec 30 Javascript
vue.js选中动态绑定的radio的指定项
Jun 02 Javascript
js使用ajax传值给后台,后台返回字符串处理方法
Aug 08 Javascript
JS如何实现封装列表右滑动删除收藏按钮
Jul 23 Javascript
SpringBoot+Vue 前后端合并部署的配置方法
Dec 30 Vue.js
NPM 安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
Dec 20 #Javascript
js多个物体运动功能实例分析
Dec 20 #Javascript
JS高级运动实例分析
Dec 20 #Javascript
CSS+jQuery实现简单的折叠菜单
Dec 20 #Javascript
jQuery常见的选择器及用法介绍
Dec 20 #Javascript
JS基于面向对象实现的选项卡效果示例
Dec 20 #Javascript
解决Angular.Js与Django标签冲突的方案
Dec 20 #Javascript
You might like
PHP 出现乱码和Sessions验证问题的解决方法!
2008/12/06 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
二进制交叉权限微型php类分享
2014/02/07 PHP
初识PHP
2014/09/28 PHP
php cookie中点号(句号)自动转为下划线问题
2014/10/21 PHP
php远程下载类分享
2016/04/13 PHP
php利用imagemagick实现复古老照片效果实例
2017/02/16 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
Thinkphp5行为使用方法汇总
2017/12/21 PHP
window.parent调用父框架时 ie跟火狐不兼容问题
2009/07/30 Javascript
JSON 编辑器实现代码
2009/12/06 Javascript
js onload处理html页面加载之后的事件
2013/10/30 Javascript
页面加载完成后再执行JS的jquery写法以及区别说明
2014/02/22 Javascript
基于socket.io和node.js搭建即时通信系统
2014/07/30 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
2014/08/27 Javascript
jQuery弹出框代码封装DialogHelper
2015/01/30 Javascript
jquery仅用6行代码实现滑动门效果
2015/09/07 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
JS控件bootstrap suggest plugin使用方法详解
2017/03/25 Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
2017/08/08 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
JavaScript事件发布/订阅模式原理与用法分析
2018/08/21 Javascript
详解VUE前端按钮权限控制
2019/04/26 Javascript
js变量值传到php过程详解 将php解析成数据
2019/06/26 Javascript
用Cython加速Python到“起飞”(推荐)
2019/08/01 Python
python从zip中删除指定后缀文件(推荐)
2019/12/05 Python
keras实现VGG16 CIFAR10数据集方式
2020/07/07 Python
html5实现九宫格抽奖可固定抽中某项奖品
2020/06/15 HTML / CSS
加拿大休闲和工业服装和鞋类零售商:L’Équipeur
2018/01/12 全球购物
光盘行动倡议书
2014/02/02 职场文书
朋友聚会开场白
2015/06/01 职场文书
python Django框架快速入门教程(后台管理)
2021/07/21 Python
阿里云 Windows server 2019 配置FTP
2022/04/28 Servers
python 学习GCN图卷积神经网络
2022/05/11 Python
Windows Server 2012 R2服务器安装与配置的完整步骤
2022/07/15 Servers