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