1. JSON
1.1. JSON
1.1.1. 什么是JSON
JSON即javascript對象表示法,是一種現在主流的數據交換格式。之所以應用廣泛還是由其簡單易讀所決定的。
簡單,只有六種類型的符號 [ ] { } ; ,就可以表示任何種類的復雜對象或數組。
易讀,機器解析還是人的閱讀都能夠從這種格式中快速找到所需要的信息。
1.1.2. 與平臺無關的數據交換
JSON作為數據交換的格式與平臺種類是無關的。不管服務器使用Java語言、C#語言或其他語言都能夠從這種字符串格式轉換為具體語言的對象。同樣,任何語言也都能將自己的對象轉換為JSON的字符串。
1.1.3. 輕量級的解決方案
JSON的輕量級是與xml這種數據交換格式相比,速度更快,文檔也更小。XML文件中會包含很多對象的層級關系,解析及轉換極不方便,字符更多導致文件過大。而這些弊端JSON都已經克服,簡單的符號是的解析更快。
1.2. JSON語法
1.2.1. JSON的結構
使用JSON進行數據交換時,主要有兩種結構,一種是使用“名稱-值”對兒的形式來表示一個對象,一種是值的有序列表,也就是數組。在這兩種結構基礎之上,相互之間可以進行嵌套。即對象的值可以是數組或對象,數組中的某個值可以是對象或數組。
不同語言之中的對象、記錄、結構、字典、哈希表等都可以作為轉換的對象基礎結構。
1.2.2. 使用JSON表示一個對象
使用JSON表示一個對象時,基本的語法結構是 以大括號開始,以大括號結尾。大括號之間的各個屬性由逗號分隔,每一組屬性由屬性名和屬性值的成對組合實現。如:要表現一個雇員對象可以按如下結構書寫:
{‘id’:1,’name’:’王小賤’,’age’:24}
所以不管多么復雜的結構,只要看到大括號就代表這個一個對象,至于內部的屬性只要保證用逗號分隔即可。
每一組屬性在書寫時要遵循以下原則:
只要對象的結構符合語法結構,那么要訪問其中某個屬性時就可以遵循“對象 . 屬性名 ”的格式來訪問其中的某個屬性值。如上面的雇員對象,想獲取name屬性的值“王小賤”就可以使用如下的代碼實現:
var obj = {‘id’:1,’name’:’王小賤’,’age’:24};
var name = obj . name ;
如果對象的某個屬性值依然是對象,那么定義結構如下:
var obj = {‘id’:1 , ’name’:’王小賤’ , ’dep’:{‘depId’:1,’depName’:’財務部’}};
var depName = obj.dep.depName ;
對象屬性可以是對象,訪問這個對象屬性的時候依然遵循“對象.屬性名”的方式來獲取,上面的對象中obj就是一個對象中還包含對象的結 構,dep是屬性名,{‘depId’:1,’depName’:’財務部’}是屬性值,即部門屬性又包括部門編號、部門名稱這兩個屬性,所以要想訪問屬 性中的屬性使用多級的點格式即可。
1.2.3. 使用JSON表示一個數組
使用JSON表示數組的時候,一定以方括號開始,以方括號結尾。所以只要看到方括號就要想到這是一個數組,數組內的多個值之間用逗號隔開。語法如下:
[ value , value , value … ]
value的類型可以是string、number、false、true、null、object、array。如果要表示3個員工的數組就可以使用如下形式:
var jsonArr = [{‘id’:1 , ’name’:’王小賤’} , {‘id’:2,’name’:’黃小仙’} , {‘id’:3,’name’:’王老頭’}];
如果要訪問數組中第二個元素的姓名,那么代碼如下:
var name = jsonArr[1].name;
數組中的元素依然可以嵌套使用數組,對象的屬性也可以嵌套數組,有如下代碼:
var jsonObj = {‘id’:1 , ‘name’:’王小賤’ , ‘salary’:[{‘month’:1 , ‘number’:5000},{‘month’:2 , ‘number’:4000 }]};
對于嵌套的數據類型,遵循原則就是:是對象就通過“.”來訪問,是數組就通過“[ ] ”下標來訪問。針對上面的對象,要想知道員工2月份的工資是多少,訪問形式如下:
var number = jsonObj.salary[1].number;
2. 使用JSON實現數據交換
2.1. 數據交換
2.1.1. 數據交換原理
JSON作為數據的交換格式,在客戶端和服務器端都要有對應的轉換過程。如果是客戶端請求數據,那么服務器端就將Java對象先轉換成 JSON字符串,經響應把字符串傳到客戶端之后,客戶端就會接收到這個轉換結果,但Javascript要求把這個字符串變成對象格式才更方便訪問,所以 在客戶端的JavaScript代碼中又需要將這個JSON字符串變成JavaScript能夠識別的對象,這樣就完成了從服務器端的對象到客戶端對象的 整個轉變過程。
同理,如果在客戶端填寫了數據后想提交給服務器,首先是將客戶端數據構造成一個JSON對象字符串,經網絡傳遞到服務器端,服務器端再依據轉換規則將JSON字符串變成Java識別的對象。
2.1.2. Java對象轉換成JSON
在服務器端對象的轉換過程可以使用官方提供的API,JSONObject和JSONArray分別為對象和數組的轉換類型。
使用這兩個類型進行對象轉換時代碼如下:
對于數組的轉換代碼如下:
List<Employee> emps = new ArrayList< Employee >();
for(int i=0;i<3;i++){
Employee s = new Employee ();
s.setId(i+1);
s.setName("Bear" + i);
s.setGender(“男”);
emps.add(s);
}
JSONArray jsonArr = JSONArray.fromObject(emps);
String jsonStr = jsonArr.toString();
2.1.3. JSON字符串轉換成JS對象
當JSON經傳輸到達客戶端時,需要完成JSON到JavaScript對象的轉換,如果使用JS原生的方法進行轉換的話,可以使用eval()方法,但需要在JSON的前后連接上左右圓括號,如:
var jsonObj = eval(“(“ + json “)”);
為什么要 eval這里要添加('('+json+')') 呢?
原因在于eval本身的問題。 由于json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,所以必須強制性的將它轉換成一種表達式。加上圓括號的目的是迫 使eval函數在處理JavaScript代碼的時候強制將括號內的表達式(exPRession)轉化為對象,而不是作為語句(statement)來 執行
但是需要注意的是方式eval()方法是動態執行其中字符串(可能是js腳本)的,這樣很容易會造成系統的安全問題。所以可以采用一些規避了 eval()的第三方客戶端腳本庫,如prototype.js里面提供的evalJSON()方法。通過在頁面中引入prototype.js文件后就 可以使用這個擴展庫。實現代碼如下:
<script type="text/javascript" src="js/prototype-1.6.0.3.js"></script>
<script type="text/javascript">
function f1(){
var xhr = getXhr();
xhr.open('get','quoto.do',true);
xhr.onreadystatechange=function(){
if(xhr.readyState == 4){
var txt = xhr.responseText;
//將json字符串轉換成javascript對象或者數組
var arr = txt.evalJSON();
}
};
xhr.send(null);
}
</script>
2.2. 緩存問題
2.2.1. 什么是緩存問題
IE瀏覽器提供的Ajax對象,在發送GET請求時,會先查看是否訪問過該地址,如果改地址已經訪問過,那么瀏覽器不再發送請求
表現在頁面終究是,第一次點擊某功能會得到數據,但是如果多次反復點擊想獲取最新數據時頁面不會有任何變化,因瀏覽器發現地址相同而拒絕發出請求。
但這種頁面表現只出現在IE瀏覽器中,Chrom瀏覽器和Firefox瀏覽器都能夠實現數據的獲取和頁面的刷新。
2.2.2. 如何解決緩存問題
要想解決緩存問題,就需要欺騙瀏覽器,讓它認為每次請求的地址是不一樣的。構建不同的URL需要添加上一個隨機數。代碼格式如下:
xhr.open(‘get’,’getNumber.do?’+Math.random() , true );
Math.random()可以產生0-1之間的隨機數,這樣每次都可以生成不一樣的地址,讓瀏覽器重新發送請求,以達到數據刷新的效果。
第二種解決緩存問題的方式就是不使用GET請求方式,改成POST提交的話,瀏覽器不會進行地址的判斷。
2.3. 同步問題
2.3.1. 什么是同步問題
同步請求指的是在AJAX對象發出請求后,瀏覽器要等待響應的回來之后再允許頁面繼續操作,表現形式就是頁面的假死狀態。就好像是只有做完一件事以后才能再做下一件事情。而異步是不需要這樣的等待的,有種兩件事情同時進行的感覺。
2.3.2. 如何發送同步請求
發送同步請求在于open方法的第三個參數,如果填寫false則代表同步類型的請求,為true代表異步類型的請求。
代碼如下:
xhr.open(‘get’,’check..’,false);
2.3.3. 同步請求的使用場景
同步請求一般應用在表單驗證這種必須等待驗證返回后才能點擊提交這樣的情況下。或者是在onunload事件時通知服務器客戶端的關閉也可以 用同步請求,有些應用需要知道客戶端是否關閉窗口,以此決定是否將服務器端針對該客戶端分配的相關資源什么時候釋放。如果客戶端關閉了瀏覽器,那么在 onunload事件中可以通知服務器,但是如果不等服務器返回就關掉的話,會不知道是否釋放成功,所以通常情況下就是用同步的方式來等待服務器的響應, 在一定程度上能 保證服務器資源的釋放。
新聞熱點
疑難解答