天天看點

【Jquery mobile】 跨域擷取資料問題

用了jquery mobile js的 getjson方法報:parsererror
           

寫了如下的代碼:

var params = jQuery.param({
						"name" : "value",
						"name2" : "value2",
					}, jQuery.ajaxSettings.traditional);
					
					$.ajax({
						type : "POST",
						url : "myUrl?jsonCallback=?",
						data : params,
						timeout : 30000, //逾時時間:30秒
						contentType : "application/json;charset=utf-8",
						dataType : "json",
						success : function(jqXHR, textStatus) {
							alert("success");
						},
						error : function(jqXHR, status, responseText) {
							alert("error - " + ":" + status + "-" + jqXHR.status + "-" + jqXHR.readyState + "-" + jqXHR.responseText + "-" + responseText);
						},
						complete : function(jqXHR, textStatus) {
							alert("complete - " + textStatus + "-" + jqXHR.responseText);
						}
					});
           

還是報同樣的錯;

導緻parsererror的原因和解決辦法:

1)charset=utf8 :FF下沒問題,結果在IE下就出錯了,把utf8改成utf-8就沒問題了,

2)data:"{}", data為空也一定要傳"{}";不然傳回的是xml格式的。并提示parsererror

目前就發現這兩種可能。

但是我的程式還是報parsererror。

XMLHttpRequest.readyState: 狀态碼是4

XMLHttpRequest.State:是200

後來找到這樣一片文章:

jQuery 跨域通路問題解決方法

浏覽器端跨域通路一直是個問題, 多數研發人員對待js的态度都是好了傷疤忘了疼,是以病發的時候,時不時地都要疼上一疼.記得很久以前使用iframe 加script domain 聲明,yahoo js util 的方式解決二級域名跨域通路的問題. 時間過得好快,又被拉回js戰場時, 跨域問題這個傷疤又開疼了.好在,有jquery幫忙,跨域問題似乎沒那麼難纏了.這次也借此機會對跨域問題來給刨根問底,結合實際的開發項目,查閱了相關資料,算是解決了跨域問題..有必要記下來備忘. 跨域的安全限制都是指浏覽器端來說的.伺服器端是不存在跨域安全限制的,是以通過本機伺服器端通過類似httpclient方式完成“跨域通路”的工作,然後在浏覽器端用AJAX擷取本機伺服器端“跨域通路”對應的url.來間接完成跨域通路也是可以的.但很顯然開發量比較大,但限制也最少,很多 widget開放平台server端(如sohu部落格開放平台)其實就麼搞的.不在本次讨論範圍.要讨論的是浏覽器端的真正跨域通路,推薦的是目前 jQuery $.ajax()支援get方式的跨域,這其實是采用jsonp的方式來完成的.

真實案例:

複制代碼 代碼如下:

var qsData = {'searchWord':$("#searchWord").attr("value"),'currentUserId':$("#currentUserId").attr("value"),'conditionBean.pageSize':$("#pageSize").attr("value")};

$.ajax({

async:false,

url: http://跨域的dns/document!searchJSONResult.action,

type: "GET",

dataType: 'jsonp',

jsonp: 'jsoncallback',

data: qsData,

timeout: 5000,

beforeSend: function(){

//jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了

},

success: function (json) {//用戶端jquery預先定義好的callback函數,成功擷取跨域伺服器上的json資料後,會動态執行這個callback函數

if(json.actionErrors.length!=0){

alert(json.actionErrors);

}

genDynamicContent(qsData,type,json);

},

complete: function(XMLHttpRequest, textStatus){

$.unblockUI({ fadeOut: 10 });

},

error: function(xhr){

//jsonp 方式此方法不被觸發.原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了

//請求出錯處理

alert("請求出錯(請檢查相關度網絡狀況.)");

}

});

注意:$.getJSON(" http://跨域的dns/document!searchJSONResult.action?name1="+value1+"&jsoncallback=?",

function(json){

if(json.屬性名==值){

// 執行代碼

}

});

這種方式其實是上例$.ajax({..}) api的一種進階封裝,有些$.ajax api底層的參數就被封裝而不可見了.

這樣,jquery就會拼裝成如下的url get請求

http://跨域的dns /document!searchJSONResult.action?&jsoncallback=jsonp1236827957501&_=1236828192549&searchWord=%E7%94%A8%E4%BE%8B¤tUserId=5351&conditionBean.pageSize=15

在響應端(http://跨域的dns/document!searchJSONResult.action),

通過 jsoncallback = request.getParameter("jsoncallback") 得到jquery端随後要回調的js function name:jsonp1236827957501

然後 response的内容為一個Script Tags:"jsonp1236827957501("+按請求參數生成的json數組+")";

jquery就會通過回調方法動态加載調用這個js tag:jsonp1236827957501(json數組);

這樣就達到了跨域資料交換的目的.

jsonp的最基本的原理是:動态添加一個是一緻的(qq空間就是大量采用這種方式來實作跨域資料交換的) .JSONP是一種腳本注入(Script Injection)行為,是以也有一定的安全隐患.

注意,jquey是不支援post方式跨域的.

為什麼呢?

雖然采用post +動态生成iframe是可以達到post跨域的目的(有位js牛人就是這樣把jquery1.2.5 打patch的),但這樣做是一個比較極端的方式,不建議采用.

也可以說get方式的跨域是合法的,post方式從安全角度上,被認為是不合法的, 萬不得已還是不要劍走偏鋒..

client端跨域通路的需求看來也引起w3c的注意了,看資料說html5 WebSocket标準支援跨域的資料交換,應該也是一個将來可選的跨域資料交換的解決方案.

詳細出處參考:http://www.jb51.net/article/21213.htm

目前将我的程式報錯歸類為服務端的處理吧。

待繼續研究。。。