十四、JSON、JSONP、jQuery等

一、JSON(JavaScript Object Notation)是一種在瀏覽器和服務器之間交換數據的格式,可用於傳遞對象(key-value對,數組或其他對象)。JSON可以在JavaScript裏傳遞到eval()方法中使用,也能使用Ajax方法來傳遞(例如httpWebRequest)。

JSON很像XML,但比XML要輕量級,都可以自描述,通過層級的形式,能被多種語言解析和使用。

格式:最完整格式{root:[{attr1:value1},...,{attrn:valuen}]}

注:{}表示一個容器,如外層的{}表示json對象,裏層的{}表示key-value對對象。[]表示數組。名稱和值用冒號隔開。數組元素之間通過逗號隔開。

如何使用JSON:

1.JSONObject實現JavaBean和json對象之間的相互轉換。

javaBean-->json對象          JSONObject     jsonObject = JSONObject.fromObject(javaBean);

json對象-->javaBean          Object                javaBean   = JSONObject.toBean(jsonObject);

2.Jsonarray實現java集合與json對象之間的相互轉換。

java集合-->json對象           JSONArray         jsonArray   = JSONArray.fromObject(java集合);

json對象-->java數組           Object                 array           = JSONArray.toArray(jsonArray);

json對象-->List                    Object                 list               = JSONArray.toList(jsonArray);


Json依賴JavaScript,因爲json是javascript對象的字符串表示。可以將json數據作爲調用的javascript函數的參數傳遞。示例如下:

<script type="text/javascript">
function functionName(data) {
    alert("attr1 : " + data.attr1 + ", attr2: " + data.attr2);
}
</script>
<script type="text/javascript">
functionName({attr1 : value1, attr2: value2});
</script>
上面是將靜態json數據作爲參數調用 JavaScript 函數。不過通過在函數調用中動態包裝json數據可以用動態數據調用函數,這是一種動態 JavaScript 插入的技術。
要查看其效果,將上面
showPrice({attr1 : value1, attr2: value2});
一行放入如下的 dynamicway.js 的獨立 JavaScript 文件中。
<script type="text/javascript">
function functionName(data) {
    alert("attr1 : " + data.attr1 + ", attr2: " + data.attr2);
}
var url = “dynamicway.js”; // URL of the external script
// this shows dynamic script insertion
var script = document.createElement('script');
script.setAttribute('src', url);

// load the script
document.getElementsByTagName('head')[0].appendChild(script); 
</script>
動態插入的 JavaScript 代碼位於 dynamicway.js 文件中,它將真正的json數據作爲參數調用 functionName()函數。
同源策略不阻止將動態腳本元素插入文檔中。也就是說,可以動態插入來自不同域的 JavaScript,並且這些域都攜帶 JSON 數據。注意,爲了完成該操作,Web 頁面必須在插入時具有已經定義好的回調函數,也就是我們例子中的 functionName()


 

二、JSONP(JSON with Padding --打包在函數調用中的 JSON 數據)

        所謂的 JSONP (JSON with Padding)服務(或 Remote JSON Service)是一種帶有附加功能的 Web 服務,該功能支持在特定的函數調用中打包返回的 JSON 數據。這種方法依賴於接受回調函數名作爲請求參數的遠程服務。然後該服務生成對該函數的調用,將 JSON 數據作爲參數傳遞,在到達客戶端時將其插入 Web 頁面並開始執行。

        JSONP 允許在服務器端集成Script tags返回給客戶端,通過JavaScript callback的形式實現跨域訪問。由於JSON是含有簡單括號結構的純文本,因此很多通道都可以交換JSON數據。因爲同源策略的限制,我們不能在與外部服務器進行通信的時候使用XMLHttpRequest,而JSONP是一種可以通過使用JSON與<script>標記相結合的方式來繞過同源策略的方法,所以可以從服務器端直接返回可執行的JavaScript函數調用或者JavaScript對象。

如何使用JSONP

         在上面的例子中,使用了靜態文件(dynamicway.js)將 JavaScript 動態插入到 Web 頁面中。儘管返回了 JSONP 回覆,但它不允許您在 URL 中定義回調函數名,這還不是真正的JSONP 服務。因此,如何才能將其轉換爲真正的 JSONP 服務呢?

 

首先,假設在所請求的 URL 中接受了一個名爲 callback 的參數。(參數名不重要,但是客戶端和服務器必須保持名稱)。假設向服務發送的請求是這樣的:

http://www.yourdomain.com/jsonp/functionname?attr1=value1&callback=value2
在這種情況下,在這種情況下,symbol 是表示請求 functionname attr1的請求參數,而 callback 是 Web 應用程序的回調函數的名稱。
使用如下代碼可以通過 jQuery 的 JSONP 支持調用該服務:
jQuery.getJSON("http://www.yourdomain.com/jsonp/functionname?attr1=value1&callback=?", 
function(data) {
    alert("attr1 : " + data.attr1 + ", attr2: " + data.attr2);
});
我們使用 ? 作爲回調函數名,而非真實的函數名。因爲 jQuery 會用生成的函數名替換 ?
下面用Java servlet實現jsonp服務:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	String jsonData = getDataAsJson(req.getParameter("attr2"));
	String output = req.getParameter("callback") + "(" + jsonData + ");";

	resp.setContentType("text/javascript");
          
	PrintWriter out = resp.getWriter();
	out.println(output);
}
 

 

三、jQuery對JSONP的支持

        jQuery擁有對JSONP回調的本地支持。如果指定了JSONP回調,就可以加載位於另一個域的JSON數據。jQuery也能優化非跨域調用,如果向同一個域發出請求,jQuery就將其轉化爲普通Ajax請求。

        回調的語法爲url&callback=?                          jQuery會自動將?替換爲要調用的生成函數名。示例如下:

jQuery.getJSON(url+"&callback=?",function(data){

      alert("attr1:"+data.value1+",attr2:"+data.value2);

});

jQuery 將一個全局函數附加到插入腳本時需要調用的對象。

另外,jQuery 也能優化非跨域調用。如果向同一個域發出請求,jQuery 就將其轉化爲普通 Ajax 請求。

 

 

注:同源策略限制

同源策略阻止從一個域上加載的腳本獲取或操作另一個域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當前 Web 頁面的域相同。這意味着瀏覽器隔離來自不同源的內容,以防止它們之間的操作。

克服該限制的一個相對簡單的方法是讓 Web 頁面向它源自的 Web 服務器請求數據,並且讓 Web 服務器像代理一樣將請求轉發給真正的第三方服務器。儘管該技術獲得了普遍使用,但它是不可伸縮的。

另一種方式是使用框架要素在當前 Web 頁面中創建新區域,並且使用 GET 請求獲取任何第三方資源。不過,獲取資源後,框架中的內容會受到同源策略的限制。

克服該限制更理想方法是在 Web 頁面中插入動態腳本元素,該頁面源指向其他域中的服務URL 並且在自身腳本中獲取數據。腳本加載時它開始執行。該方法是可行的,因爲同源策略不阻止動態腳本插入,並且將腳本看作是從提供 Web 頁面的域上加載的。但如果該腳本嘗試從另一個域上加載文檔,就不會成功。幸運的是,通過添加 JavaScript Object Notation (JSON) 可以改進該技術

發佈了42 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章