參考文章:【原創】說說JSON和JSONP,也許你會豁然開朗,含jQuery用例
使用 JSONP 跨站請求
JSON為JavaScript中常用的資料交換格式
簡單、輕型的特性讓他成為Web 開發的首選,這裡就不多提了
而在Web開發的過程中,我們有時會遇到跨網域存取資料的需求
不管是基於分散流量需求,又或者是使用雲端提供業者的服務
使用第三方提供的服務、資源
甚至在同一個專案目錄底下開發的檔案也可能因啟用HTTPS而導致網域的不同
我們有這麼多會碰上跨網域的情況
但Browser 本身的安全機制會禁止我們直接從其他網域取得資料
瀏覽器唯一能從其他網域取得資源的機會就是JavaScript的匯入
也因此衍伸出一個非官方的解決方案,也就是JSONP
JSONP的全名是JSON with Padding
這項技巧本身與JSON沒有實際關係,僅僅是因為JSON是實作上最使用的格式
JSONP簡單的來說即是利用JavaScript的動態載入
將JSON格式的資料讀取進來後,直接在JavaScript做處理
這與 AJAX是不同的技術方式
AJAX的目的是獲取目標頁面的資料,而JSONP則是獲取一段JavaScript程式碼
欲取得資料的頁面寫下類似下面這段程式碼:
var head = document.getElementsByTagName('head')[0];
var storeList = null;
//倒入JSON資料到storeList
var JSONDataGetter = function(data){
storeList = JSON.parse(JSON.stringify(data));
};
var src = "firmList.jsp"; //JSON資料提供頁面
var js = document.createElement('script');
js.setAttribute('src', src);
if(head)
head.appendChild(js);
else
document.body.appendChild(js);
上面這段的 JSONDataGetter() 會將傳入的JSON資料轉成JavaScript物件
接著是JSON資料提供頁面的程式碼
<%
response.setContentType("text/javascript"); //將頁面的型別設定為JavaScript
.... //JSP code
int counter = 0;
out.print("JSONDataGetter([");
for(Map.Entry<String, HashMap<String, String>> m : totalMap.entrySet()){
HashMap<String, String> store = m.getValue();
if(counter == 0){
out.print(String.format("{ \"storeName\" : \"%s\", \"storeType\" : \"%s\", \"storeLocation\" : \"%s\"}", m.getKey(), store.get("storeType"), store.get("storeLocation")));
}else{
out.print(String.format(", { \"storeName\" : \"%s\", \"storeType\" : \"%s\", \"storeLocation\" : \"%s\"}", m.getKey(), store.get("storeType"), store.get("storeLocation")));
}
counter++;
}
out.print("]);");
%>
大部分都是字串拼貼的處理,顯示出來大概就是下面這樣
JSONDataGetter([ //JSON資料]);
引入的JavaScript code的作用是呼叫 JSONDataGetter() 函式處理產生的JSON資料
實務上也會常看到在引入JavaScript的路徑上加上callback變數回傳
如:var src = "firmList.jsp?callback=XXX";
提供 JSON 資料的頁面再根據參數而輸出不同的字串,以便呼叫不同的處理函式
如此一來就能做到更多元的處理
這就是JSONP了
要說明的是JSONP送出資料是使用GET方式
如果有需要透過POST方法送出資料,可以參考Ajax跨網域議題 - 透過POST方法送出資料
使用 JSONP 跨站請求
JSON為JavaScript中常用的資料交換格式
簡單、輕型的特性讓他成為Web 開發的首選,這裡就不多提了
而在Web開發的過程中,我們有時會遇到跨網域存取資料的需求
不管是基於分散流量需求,又或者是使用雲端提供業者的服務
使用第三方提供的服務、資源
甚至在同一個專案目錄底下開發的檔案也可能因啟用HTTPS而導致網域的不同
我們有這麼多會碰上跨網域的情況
但Browser 本身的安全機制會禁止我們直接從其他網域取得資料
瀏覽器唯一能從其他網域取得資源的機會就是JavaScript的匯入
也因此衍伸出一個非官方的解決方案,也就是JSONP
JSONP的全名是JSON with Padding
這項技巧本身與JSON沒有實際關係,僅僅是因為JSON是實作上最使用的格式
JSONP簡單的來說即是利用JavaScript的動態載入
將JSON格式的資料讀取進來後,直接在JavaScript做處理
這與 AJAX是不同的技術方式
AJAX的目的是獲取目標頁面的資料,而JSONP則是獲取一段JavaScript程式碼
欲取得資料的頁面寫下類似下面這段程式碼:
var head = document.getElementsByTagName('head')[0];
var storeList = null;
//倒入JSON資料到storeList
var JSONDataGetter = function(data){
storeList = JSON.parse(JSON.stringify(data));
};
var src = "firmList.jsp"; //JSON資料提供頁面
var js = document.createElement('script');
js.setAttribute('src', src);
if(head)
head.appendChild(js);
else
document.body.appendChild(js);
上面這段的 JSONDataGetter() 會將傳入的JSON資料轉成JavaScript物件
接著是JSON資料提供頁面的程式碼
<%
response.setContentType("text/javascript"); //將頁面的型別設定為JavaScript
.... //JSP code
int counter = 0;
out.print("JSONDataGetter([");
for(Map.Entry<String, HashMap<String, String>> m : totalMap.entrySet()){
HashMap<String, String> store = m.getValue();
if(counter == 0){
out.print(String.format("{ \"storeName\" : \"%s\", \"storeType\" : \"%s\", \"storeLocation\" : \"%s\"}", m.getKey(), store.get("storeType"), store.get("storeLocation")));
}else{
out.print(String.format(", { \"storeName\" : \"%s\", \"storeType\" : \"%s\", \"storeLocation\" : \"%s\"}", m.getKey(), store.get("storeType"), store.get("storeLocation")));
}
counter++;
}
out.print("]);");
%>
大部分都是字串拼貼的處理,顯示出來大概就是下面這樣
JSONDataGetter([ //JSON資料]);
引入的JavaScript code的作用是呼叫 JSONDataGetter() 函式處理產生的JSON資料
實務上也會常看到在引入JavaScript的路徑上加上callback變數回傳
如:var src = "firmList.jsp?callback=XXX";
提供 JSON 資料的頁面再根據參數而輸出不同的字串,以便呼叫不同的處理函式
如此一來就能做到更多元的處理
這就是JSONP了
要說明的是JSONP送出資料是使用GET方式
如果有需要透過POST方法送出資料,可以參考Ajax跨網域議題 - 透過POST方法送出資料
留言
張貼留言