一、什麼是跨域?
由於瀏覽器出於安全的考慮,採取了同源策略的限制,使得jQuery無法直接跨網域名稱互相操作對象或資料。例如:a.com 網域名稱下的
a.html頁面利用jQuery無法操作b.com 網域名稱下b.html頁面的對象或是資料, 並且預設情況下也不能操作test.a.com網域名稱下的
test.html的 對象或是資料 。只要滿足下麵條件的jQuery都會視為跨網域名稱:
1.主域相同,子域不同,如xxx.aaa.com和yyy.aaa.com
2.網域名稱相同,連接埠不同,如xxx.aaa.com:8000和xxx.aaa.com
3.網域名稱相同,協議不同,如http://www.aaa.com/和https://www.aaa.com/
只有協議、網域名稱、連接埠三者完全相同jQuery才會視為不是跨網域名稱的。
二、解決jQuery跨網域名稱操作對象的方法
1、頂級網域名稱一至的情況
預設情況下 a.com 網域名稱下的 a.html頁面利用jQuery 不能操作test.a.com網域名稱下的 test.html的對象或是資料。但對於這種頂級網域名稱相同的情況只要在a.html和test.html中重設document.domain=a.com便可。
2、頂級網域名稱不一至的情況
對於 a.com 網域名稱下的 a.html頁面利用jQuery操作b.com網域名稱下的b.html頁面中的資料有兩方法 $.getJSON 、$.ajax
(1)通過jQuery的ajax進行跨域,這其實是採用的jsonp的方式來實現的。
jsonp是英文json with padding的縮寫。它允許在伺服器端產生script tags至返回至用戶端,也就是動態產生javascript標籤,
通過javascript callback的形式實現資料讀取。
html頁面端範例程式碼:
代碼如下:
//首先要引入jquery的js包 jQuery(document).ready(function(){ $.ajax({ type : "get", //jquey是不支援post方式跨域的 async:false, url : "http://api.jb51.net/apitools/ajax_props.do", //跨域請求的URL dataType : "jsonp", //傳遞給請求處理常式,用以獲得jsonp回呼函數名的參數名(預設為:callback) jsonp: "jsoncallback", //自訂的jsonp回呼函數名稱,預設為jQuery自動產生的隨機函數名 jsonpCallback:"success_jsonpCallback", //成功擷取跨網域服務器上的json資料後,會動態執行這個callback函數 success : function(json){ alert(json); } }); });
伺服器端範例程式碼,以java為例:
伺服器端代碼,是重點,開始以為,只要用戶端通過jsonp就可以直接跨域訪問,其實不然,需要伺服器端的支援才行。
代碼如下 :
public void jsonpTest() throws IOException{ HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); //根據html指定的jsonp回呼函數的參數名,擷取回呼函數的名稱 //callbackName的值其實就是:success_jsonpCallback String callbackName = (String)request.getAttribute("jsoncallback"); //簡單類比一個json字串,實際可使用google的gson進行轉換,次數通過字串拼接 //{"name":"張三","age":28} //\是對"號進行轉義 String jsonStr = "{\"name\":\"張三\",\"age\":28}"; //最終返回的資料為:success_jsonpCallback({"name":"張三","age":28}) String renderStr = callbackName+"("+jsonStr+")"; response.setContentType("text/plain;charset=UTF-8"); response.getWriter().write(renderStr); }
jsonp的原理:
首先在用戶端註冊一個callback (如:'jsoncallback'), 然後把callback的名字(如:success_jsonpCallback)傳給伺服器端對應的處理函數。
伺服器先產生需要返回給用戶端的 json 資料。然後以 javascript 文法的方式,產生一個function , function 名字就是傳遞上來的參數(jsoncallback)的值(success_jsonpCallback) 。
最後將 json 資料直接以入參的方式,放置到 function 中,這樣就產生了一段 js 文法的文檔,返回給用戶端。
用戶端瀏覽器,解析script標籤,並將伺服器端返回的資料,作為參數,
傳入到了用戶端預先定義好的 callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裡。
實際上跨域是通過動態增加script來載入資料,無法直接獲得資料,所以需要使用回呼函數。
(2)使用jquery的getJson進行跨域讀取資料
實際上getJson方式的根本原理和ajax使用jsonp的方式是一樣的。
jquery中常用getJson來調用擷取遠端資料,並通過json格式返回。函數的原型如下:
jQuery.getJSON(url,data,success(data,status,xhr))
參數描述
url必需。規定將請求發送的哪個 URL。
data可選。規定連同請求發送到伺服器的資料。
success(data,status,xhr)可選。規定當請求成功時啟動並執行函數。
額外的參數:
response - 包含來自請求的結果資料
status - 包含請求的狀態
xhr - 包含 XMLHttpRequest 對象
該函數是簡寫的ajax函數,實際上等價於:
代碼如下:
$.ajax({ url: url, data: data, success: callback, dataType: json});
言歸正傳,下面我們來看如何使用getJson跨域擷取資料。
html頁面範例程式碼:
代碼如下:
$.getJSON("http://api.jb51.net/apitools/ajax_props.do&jsoncallback=?", function (data) { alert(data); });
執行原理:
發送請求時需要傳一個callback的回呼函數名到伺服器端,伺服器端拿到這個回呼函數名,再將返回資料用參數的形式反回到用戶端,這樣用戶端就能夠調到。
所以發送請求URL的地址後面一定要上jsoncallback=?這樣的參數,jquery會將?號自動替換成自動產生的回呼函數的名稱。
所以最終的實際請求為:http://api.jb51.net/apitools/ajax_props.do&jsoncallback=jsonp1322444422697
所以和ajax的方式想比較,也就是callback函數一個是自動產生的函數名,一個是手工指定的函數名。
注意以下幾點:
1.發送到資料接收方的地址後面一定要加上callback=?這樣的參數,且這個?是會被Jquery自動替換成回調方法的名稱。(在Jquery1.4中可以自己指定回調方法的名稱了)
2.注意js指令碼發送資料的data不能寫成var data="{'username':'sanjer','userid':'110'}";而是要寫成var data={username:'sanjer',userid:'110'},這點要注意。要想接收伺服器端返回的資料必須伺服器端封裝資料為JSON格式字串並和callback值一道返回。(請仔細看上面的範例程式碼)。
3.由於調用Jquery的$.getJSON方法時,Jquery有自己的處理,實際上通過script的scr請求的,但要知道,資料最終還是通過url後面通過get方式發送資料出去的,這就決定了,發送的data資料量不能太多,否則造成url太長接收失敗(getJSON方式是不可能有post方式遞交的)。
如果要跨域發送大資料量則選用jQuery提供的ajax方法,最好不選用getJSON方法。
4.以上的例子是站在兩方面的開發都由你掌控的前提下的。且要注意伺服器程式端的安全係數不高(建議資料接收端這邊不要放重要、敏感的邏輯處理單元)。
以上這篇java 結合jQuery實現跨網域名稱擷取資料的方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援雲棲社區。