首頁 > web前端 > js教程 > 主體

ajax跨域呼叫webservice的實作程式碼_javascript技巧

WBOY
發布: 2016-05-16 09:00:23
原創
2022 人瀏覽過

  最近ajax訪問webservice遇到跨域的問題,網上搜尋資料,總結如下(很多都是覺得人家總結不錯的複製下來)

  >

  先上我的已實作程式碼:

  前端程式碼:

$.ajax({
 type: "get",
 url: "http://localhost/service1.asmx/getelevatorstatusjsondata?jsoncallback=?",
 datatype: "jsonp",
 jsonp: "json",
 data: "",
 success: function (result) {
 var data = eval(result);
 for (var i = 0; i < data.length; i++) {
 alert(data[i].id + "--" + data[i].name);
 }
 },
 error: function (a, b, c) {
 alert(c);
 }
 }); 
登入後複製

  服務端程式碼:

 /// <summary>
 /// 获取状态数据信息
 /// </summary>
 /// <returns></returns>
 [webmethod]
 public void getelevatorstatusjsondata()
 {
 list<list<deviceinfo>> elevatordatas = new list<list<deviceinfo>>();
 list<senddicdate> searchlist = xmlserializehelper.xmldeserializefromfile<list<senddicdate>>(@configutil.servicepath + configutil.getconfigbykey("xmlpath") + "查询指令信息.xml", encoding.utf8);
 foreach (senddicdate item in searchlist)
 {
 string key = item.portno + "-" + item.bordrate + "-" + item.sendtype;
 list<deviceinfo> deviceinfolist = (list<deviceinfo>)context.cache.get(key);
 elevatordatas.add(deviceinfolist);
 }

 string result = "";
 datacontractjsonserializer json = new datacontractjsonserializer(elevatordatas.gettype());
 using (memorystream stream = new memorystream())
 {
 json.writeobject(stream, elevatordatas);
 result = encoding.utf8.getstring(stream.toarray());
 }
 string jsoncallback = httpcontext.current.request["jsoncallback"];
 result = jsoncallback + '(' + result + ')';
 httpcontext.current.response.write(result);
 httpcontext.current.response.end();

 }
登入後複製

  c#

   以上是呼叫c#服務端的實作程式碼,下面的是java端的,參數可能有差異,但原理是相通的

  java:

  

string callbackfunname = context.request["callbackparam"];
  context.response.write(callbackfunname + "([ { \"name\":\"john\"}])");
登入後複製

  ps:客戶端的jsonp參數是用來透過url傳參,傳遞jsonpcallback參數的參數名,比較拗口,通俗點講:

  jsonp: ""

  jsonpcallback:""

  順帶一提:在chrome瀏覽器裡,也可以在服務端設定header訊息context.response.addheader("access-control-allow-origin", "*");來達到跨網域要求的目的,且不需要設定ajax以下參數

  

datatype : "jsonp",
  jsonp: "callbackparam",
  jsonpcallback:"jsonpcallback1"
登入後複製

  以正常ajax請求方式就可以取得資料。

下面是原理,看別人講解的,感覺很有道理:

  1、一個眾所周知的問題,ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、wcf,只要是跨域請求,一律不准;

  2、不過我們又發現,web頁面上調用js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有」src」這個屬性的標籤都擁有跨域的能力,例如

  3、於是可以判斷,當前階段如果想透過純web端(activex控制項、服務端代理、屬於未來的html5之websocket等方式不算)跨網域存取資料就只有一種可能,那就是在遠端伺服器上設法把資料裝進js格式的檔案裡,供客戶端呼叫和進一步處理;

  4、恰巧我們已經知道有一種叫做json的純字符數據格式可以簡潔的描述複雜數據,更妙的是json還被js原生支持,所以在客戶端幾乎可以隨心所欲的處理這種格式的數據;

  5、這樣子解決方案就呼之欲出了,web客戶端透過與調用腳本一模一樣的方式,來調用跨域伺服器上動態生成的js格式檔案(一般以json為後綴),顯而易見,伺服器之所以要動態產生json文件,目的就在於把客戶端需要的資料裝進去。

  6、客戶端在對json檔案呼叫成功之後,也就獲得了自己所需的數據,剩下的就是按照自己需求進行處理和展現了,這種獲取遠端數據的方式看起來非常像ajax ,但其實不一樣。

  7、為了方便客戶端使用數據,逐漸形成了一種非正式傳輸協議,人們把它稱作jsonp,該協議的一個要點就是允許用戶傳遞一個callback 參數給服務端,然後服務端返回數據時會將這個callback參數當作函數名稱來包裹住json數據,這樣客戶端就可以隨意自訂自己的函數來自動處理回傳資料了。

  聰明的開發者很容易想到,只要服務端提供的js腳本是動態生成的就行了嗔,這樣呼叫者可以傳一個參數過去告訴服務端「我想要一段呼叫xxx函數的js程式碼,請你回傳給我”,於是伺服器就可以按照客戶端的需求來產生js腳本並回應了。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script type="text/javascript">// 得到航班信息查询结果后的回调函数var flightHandler =function(data){
 alert('你查询的航班结果是:piao价 '+ data.price +' 元,'+'余piao '+ data.tickets +' 张。');
 }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)var url ="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性var script = document.createElement('script');
 script.setAttribute('src', url); 
 // 把script标签加入head,此时调用开始 
//document.getElementsByTagName('head')[0].appendChild(script); 
</script></head><body></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Untitled Page</title><script type="text/javascript" src=jquery.min.js"></script><script type="text/javascript">
 jQuery(document).ready(function(){
 $.ajax({
 type: "get",
 async: false,
 url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
 dataType: "jsonp",
 jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){
 alert('您查询到航班信息:piao价: '+ json.price +' 元,余piao: '+ json.tickets +' 张。');
 },
 error: function(){
 alert('fail');
 }
 });
 }); </script></head><body></body></html>
登入後複製

是不是有點奇怪?為什麼我這次沒有寫flighthandler這個函式呢?而且竟然也運作成功了!哈哈,這就是jquery的功勞了,jquery在處理jsonp類型的ajax時(還是忍不住吐槽,雖然jquery也把jsonp歸入了ajax,但其實它們真的不是一回事),自動幫你生成回調函數並把資料取出來供success屬性方法來調用,是不是很爽呀?

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!