用jQuery.ajaxSetup實(shí)現(xiàn)對請求和響應(yīng)數(shù)據(jù)的過濾
不知道同學(xué)們在做項(xiàng)目的過程中有沒有相同的經(jīng)歷呢?在使用 ajax 的時(shí)候,需要對請求參數(shù)和響應(yīng)數(shù)據(jù)進(jìn)行過濾處理,比如你們覺得就讓請求參數(shù)和響應(yīng)信息就這么赤裸裸的在互聯(lián)網(wǎng)里來回的穿梭,比如這樣:
要知道,在浩瀚的互聯(lián)網(wǎng)中,所有的信息都是不安全的,萬一有人偷窺我們怎么辦?!萬一被別人看見了我們的美體,偷窺到了我們的私處,然后以此威脅我們,豈不是太難堪了不是?這時(shí),你或許會(huì)想給請求數(shù)據(jù)和響應(yīng)數(shù)據(jù)加密,就相當(dāng)于給我們的數(shù)據(jù)穿上了一層衣服。于是我們這樣:
是不是美美噠,對,穿上一層漂漂亮亮的衣服,就不怕別人偷窺我們的美體了,我們出門的時(shí)候要穿衣服,回家的時(shí)候也要脫衣服,也就是說ajax請求的參數(shù)需要加密,ajax響應(yīng)的數(shù)據(jù)的要解密,如果說項(xiàng)目只有幾個(gè)ajax請求需要加密的話還OK,發(fā)請求之前把data處理一遍,success回調(diào)函數(shù)把responseText解密一遍就完了??墒翘热艏軜?gòu)大一點(diǎn),ajax請求多一點(diǎn),每次請求響應(yīng)都要單獨(dú)處理加密解密啟不是太冗余了,于是我便去翻閱jQuery ajax參考手冊,還真的有不小的收獲。
首先jQuery有一個(gè) ajaxSetup 方法,該方法可以設(shè)置全局 ajax 初始化參數(shù),也就是說在聲明了該方法之后的所有 ajax 請求都會(huì)默認(rèn)使用該方法設(shè)置的初始值。
然后我們再翻閱 ajax 參數(shù),突然,我眼前一亮!有一個(gè)叫做 beforeSend 的方法,我一看這名字就亮了!這個(gè)函數(shù)也就是在發(fā)送 ajax 請求之前的回調(diào)函數(shù),于是我們先把它用起來:
$.ajaxSetup({ beforeSend: function() { console.log(arguments);//我們先來看看這里面有什么好玩的東西 } });
然后我們在隨便發(fā)一個(gè) ajax 請求:
$.ajax({ url: 'SetupServlet', type: 'GET', data: { param1: 'test1', param2: 'test2', } });
在控制臺我們可以看見打印的參數(shù)列表有兩個(gè)對象,我們先來看看 W3C 里對 beforeSend 的解釋:
- beforeSend(XHR)
- 類型:Function
- 發(fā)送請求前可修改 XMLHttpRequest 對象的函數(shù),如添加自定義 HTTP 頭。
- XMLHttpRequest 對象是唯一的參數(shù)。
- 這是一個(gè) Ajax 事件。如果返回 false 可以取消本次 ajax 請求。
實(shí)際上這里是不對的,因?yàn)閄HR不是唯一的參數(shù),XHR只是 arguments[0] ,我們還有一個(gè) arguments[1],我們來看看這是什么東西:
以下是在 Firefox Developer Edition(Firefox 的開發(fā)者版本,最近發(fā)現(xiàn)的,絕得超好用) 中打印的東西:
看到這里我們大致明白了,我們這個(gè)對象大致就是 ajax 的參數(shù)對象,由于我們本次實(shí)驗(yàn)的目的是給我們將要在互聯(lián)網(wǎng)中遨游的數(shù)據(jù)穿衣服,那么我們看看這個(gè)衣服該穿在哪呢?在這個(gè)對象的 url 我們可以看到,jQuery 的 ajax 操作已經(jīng)我們之前傳進(jìn)來的參數(shù)序列化并附加在了 url 后面,因?yàn)檫@是 GET 請求。那么 POST 請求長什么樣呢?我們再來試一下:
$.ajax({ url: 'SetupServlet', type: 'POST', data: { param1: 'test1', param2: 'test2', }, });
現(xiàn)在這個(gè)參數(shù)對象長這個(gè)樣子:
我們可以看到不同之處在于 POST 請求多了一個(gè) data 屬性,并且 url 后面沒有參數(shù)序列化字符串,但是 data 屬性卻是序列化之后的參數(shù)字符串。至此我們已經(jīng)可以在 beforeSend 函數(shù)中對請求前的參數(shù)進(jìn)行修改了,GET 請求修改 url 后面的參數(shù),POST 請求修改 data 中的值,具體效果在這里暫時(shí)不演示。
但是到這里我依舊不是很爽啊,因?yàn)闊o論是 GET 還是 POST 的,我得到的都是序列化之后的字符串,要修改參數(shù)的話得先反序列化,然后才能處理,于是我又在 ajax API 當(dāng)中尋找,功夫不負(fù)有心人,我找到了一個(gè)叫做 processData 的東西,先來看看官方解釋:
- processData
- 類型:Boolean
- 默認(rèn)值: true。默認(rèn)情況下,通過data選項(xiàng)傳遞進(jìn)來的數(shù)據(jù),如果是一個(gè)對象(技術(shù)上講只要不是字符串),都會(huì)處理轉(zhuǎn)化成一個(gè)查詢字符串,以配合默認(rèn)內(nèi)容類型 "application/x-www-form-urlencoded"。如果要發(fā)送 DOM 樹信息或其它不希望轉(zhuǎn)換的信息,請?jiān)O(shè)置為 false。
也就是說默認(rèn)情況下 jQuery 會(huì)自動(dòng)幫我們把參數(shù)序列化,那么我們現(xiàn)在把它設(shè)置為 false 看看會(huì)發(fā)生什么:
$.ajaxSetup({ beforeSend: function() { console.log(arguments); }, processData: false, });
這時(shí)請求中的參數(shù)會(huì)發(fā)生如下變化
GET:
POST:
這里我只截取部分截圖,我們看到我們傳進(jìn)來的參數(shù)在 POST 請求就是原生的對象,終于得到我想要的東西了,此時(shí)此刻我心中大喜!必須得抽根煙祝祝性,額不對...是祝祝興。于是我們可以拿這個(gè) data 盡情的蹂躪,隨意的鞭打,我要把這個(gè) data 對象盡情的踐踏!額,不好意思有點(diǎn)激動(dòng)?;氐秸},我們要給 data 穿衣服才對嘛,怎么說著說著就要開始脫衣服了...好的,下面我們開始穿衣服,在這里我以 base64 舉例,我對請求的參數(shù)進(jìn)行 base64 編碼:
$.ajaxSetup({ beforeSend: function() { console.log(arguments); var params = arguments[1].data; var data = ''; for (var key in params) { //這兩行代碼的意思是進(jìn)行 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);//將序列化后的參數(shù)重寫 }, processData: false, });
于是乎,我們的請求參數(shù)就穿上了一身漂漂亮亮的衣服遨游在互聯(lián)網(wǎng)的世界里了,因?yàn)?jquery 在 GET 方法中會(huì)自動(dòng)把 data 附加在 url 后面,所以將 processData 設(shè)置為 false 之后 url 后面會(huì)出現(xiàn) [object object] ,這是 javascript 對象 toString() 過后的結(jié)果,也就是說我們的這個(gè)方法并不很適合 GET 方法,所以想給數(shù)據(jù)穿衣服的同學(xué)們還是乖乖的使用 POST 方法吧。
講到這里,發(fā)送數(shù)據(jù)我們解決了,但是接受數(shù)據(jù)呢?如果接受的數(shù)據(jù)也是進(jìn)行加密的話,我們還需要對數(shù)據(jù)進(jìn)行解密(說到這里還是得脫衣服[捂臉]),我們繼續(xù)翻閱 API ,于是我又看到了一個(gè)叫做 dataFilter 的東西,老規(guī)矩,先看官方解釋:
- dataFilter
- 類型:Function
- 給 Ajax 返回的原始數(shù)據(jù)的進(jìn)行預(yù)處理的函數(shù)。提供 data 和 type 兩個(gè)參數(shù):data 是 Ajax 返回的原始數(shù)據(jù),type 是調(diào)用 jQuery.ajax 時(shí)提供的 dataType 參數(shù)。函數(shù)返回的值將由 jQuery 進(jìn)一步處理。
該函數(shù)很簡單,就兩個(gè)參數(shù),arguments[0] 是 ajax 的原始響應(yīng)數(shù)據(jù),也就是 XHR.responseText ,arguments[1] 是 ajax 請求參數(shù)中的 dataType ,而這個(gè)函數(shù)返回的值也就是 success 回調(diào)函數(shù)中的 responseText,這下就非常好辦了,我們先來測試下:
前端代碼發(fā)送 ajax 請求,后臺響應(yīng)一句 "hello" ,然后我們在 dataFilter 里返回一句 "world"
前端代碼:
$.ajaxSetup({ beforeSend: function() { console.log(arguments); var params = arguments[1].data; var data = ''; for (var key in params) { //這兩行代碼的意思是進(jìn)行 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);//將序列化后的參數(shù)重寫 }, processData: false, dataFilter: function() { console.log(arguments);//這是我的一個(gè)習(xí)慣,拿到一個(gè)函數(shù)之后,管他是什么東西,先看看里面有什么參數(shù) 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");
后端輸出:
前端輸出:
看來一切正常,現(xiàn)在我們加密和解密的過程進(jìn)行一條龍的處理:
前端:
$.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()));
后臺輸出:
前端輸出:
至此已經(jīng)大功告成了,讓我們來總結(jié)下我們使用過的東西
第一個(gè): ajaxSetup 這是設(shè)置全局的初始屬性
然后是三個(gè)屬性:
beforeSend:發(fā)送前執(zhí)行的函數(shù)
processData:默認(rèn)不序列化參數(shù)
dataFilter:對響應(yīng)的數(shù)據(jù)進(jìn)行過濾
然后,我們就可以給我們的數(shù)據(jù)穿上一層漂漂亮亮的衣服了。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
JQuery DataTable刪除行后的頁面更新利用Ajax解決
使用Jquery的DataTable進(jìn)行數(shù)據(jù)表處理非常方便,常遇到的一個(gè)問題就是刪除一行后頁面必須進(jìn)行更新,下面與大家分享下使用Ajax的解決方法2013-05-05使用jQuery中的when實(shí)現(xiàn)多個(gè)AJAX請求對應(yīng)單個(gè)回調(diào)的例子分享
我在為 Mozilla Developer Network(Mozilla開發(fā)者社區(qū)) 寫代碼時(shí)需要加載的一個(gè)普通的的腳本文件,以及一個(gè)JSON流。 因?yàn)槲覀兪褂胘Query,這意味著需要調(diào)用 jQuery.getScript 和 jQuery.getJSON 函數(shù)2014-04-04jQuery實(shí)現(xiàn)美觀的多級動(dòng)畫效果菜單代碼
這篇文章主要介紹了jQuery實(shí)現(xiàn)多級動(dòng)畫效果菜單代碼,涉及jquery針對頁面元素的遍歷及事件綁定操作頁面元素樣式變換的技巧,界面美觀實(shí)用,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09使用JQuery和CSS模擬超鏈接的用戶單擊事件的實(shí)現(xiàn)代碼
使用JQuery和CSS模擬超鏈接的用戶單擊事件的實(shí)現(xiàn)代碼,需要的朋友可以參考下2012-05-05完美解決jQuery 鼠標(biāo)快速滑過后,會(huì)執(zhí)行多次滑出的問題
下面小編就為大家?guī)硪黄昝澜鉀QjQuery 鼠標(biāo)快速滑過后,會(huì)執(zhí)行多次滑出的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12全面解析DOM操作和jQuery實(shí)現(xiàn)選項(xiàng)移動(dòng)操作代碼分享
這篇文章主要介紹了DOM操作和jQuery實(shí)現(xiàn)選項(xiàng)移動(dòng)操作代碼分享的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06Jquery和Js獲得元素標(biāo)簽名稱的方法總結(jié)
下面小編就為大家?guī)硪黄狫query和Js獲得元素標(biāo)簽名稱的方法總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-10-10