使用JSONP解決Ajax跨域訪問問題

JSONP(JSON with Padding)是JSON的一種“使用模式”,可用于解決主流浏覽器的跨域數據訪問的問題。現在我們來用JSONP解決Ajax跨域訪問問題。

前幾天,工作上有一新需求,需要前端web頁面異步調用後台的Webservice方法返回信息。實現方法有多種,本例采用 jQuery+Ajax,完成後,在本地調試了一切ok,但是部署到伺服器上以後就出現問題了,後台服務調用沒有回應,怎麽回事?代碼沒怎麽改動,唯一修改的地方就是jQuery的ajax方法中的url地址。難道是這裏的問題,經過檢查和調試,發現原來是同源策略在作怪,我們知道,JavaScript 或jQuery是在Web前端開發中經常使用的動態腳本技術。在JavaScript中,有一個很重要的安全性限制,被稱爲“Same- Origin Policy”(同源策略)。這一策略對于JavaScript代碼能夠訪問的頁面內容做了很重要的限制,即JavaScript只能訪問與包含它的文檔或腳本 在同一域名下的內容。不同域名下的腳本不能互相訪問,即便是子域也不行。關于同源策略,讀者可百度更詳細的解釋,這裏不再贅述。
但是有時候又不可避免地需要進行跨域操作,這時候“同源策略”就是一個限制了,怎麽辦呢?采用JSONP跨域GET請求是一個常用的解決方案,下面我們來看一下JSONP跨域是如何實現的,並探討下JSONP跨域的原理。
這裏提到了JSONP,那有人就問了,它同JSON有什麽區別不同和區別呢,接下我們就來看看,百度百科有以下說明:
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。 JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成爲理想的數據交換語言。易于人閱讀和編寫,同時也易于機器解析和生成(網路傳輸速度快)。
JSONP(JSON with Padding)是JSON的 一種“使用模式”,可用于解決主流浏覽器的跨域數據訪問的問題。由于同源策略,一般來說位于 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態産生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。

到這裏,應該明白了,JSON是一種輕量級的數據交換格式,像xml一樣,是用來描述數據間的。JSONP是一種使用JSON數據的方式,返回的不是JSON對象,是包含JSON對象的javaScript腳本。
那JSONP是如何工作的呢,我們知道,由于同源策略的限制,XmlHttpRequest只允許請求當前源(域名、協定、端口)的資源。若要跨域請求出于安全性考慮是不行的,但是我們發現,Web頁面上調用js文件時則不受是否跨域的影響,而且擁有”src”這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>,這時候,聰明的程序猿就想到了變通的方法,如果要進行跨域請求, 通過使用html的script標記來進行跨域請求,並在回應中返回要執行的script代碼,其中可以直接使用JSON傳遞 javascript對象。即在跨域的服務端生成JSON數據,然後包裝成script腳本回傳,著不就突破同源策略的限制,解決了跨域訪問的問題了麽。
下面我們就看下怎麽實現:
前端代碼:

代碼如下
function CallWebServiceByJsonp() {
$("#SubEquipmentDetails").html('');
$.ajax({
type: "GET",
cache: false,
url: "http://servername/webservice/webservice.asmx/GetSingleInfo",
data: { strCparent: $("#Equipment_ID").val() },
dataType: "jsonp",
//jsonp: "callback",
jsonpCallback: "OnGetMemberSuccessByjsonp"
});
}

function OnGetMemberSuccessByjsonp(data) {
//處理data
alert(data);
}


後端的WebService代碼:

代碼如下
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
public void GetSingleInfo(string strCparent)
{
string ret = string.Empty;
HttpContext.Current.Response.ContentType = "application/json;charset=utf-8";
string jsonCallBackFunName = HttpContext.Current.Request.Params["callback"].ToString();
//string jsonCallBackFunName1 = HttpContext.Current.Request.QueryString["callback"].Trim();

//上面代碼必須
//中間代碼執行自己的業務操作,可返回自己的任意信息(多數據類型)

BLL.equipment eq_bll = new BLL.equipment();
List<Model.equipment> equipmentList = new List<Model.equipment>();
equipmentList = eq_bll.GetModelEquimentList(strCparent);
ret = JsonConvert.SerializeObject(equipmentList);

//下面代碼必須
HttpContext.Current.Response.Write(string.Format("{0}({1})", jsonCallBackFunName, ret));
HttpContext.Current.Response.End();
}


如上所示,前端的CallWebServiceByJsonp方法采用jQuery的ajax方法調用後端的Web服務GetSingleInfo方法,後台的GetSingleInfo方法,使用前端的回調方法OnGetMemberSuccessByjsonp包裝後台的業務操作的JSON對象,返回給前端一段javascript片段執行。巧妙的解決了跨域訪問問題。
JSONP的缺點:
JSONP不提供錯誤處理。如果動態插入的代碼正常運行,你可以得到返回,但是如果失敗了,那麽什麽都不會發生。

更多相關文章
  • 關于跨域問題一直是我們比較糾結的地方,下面我來總結一下關于ajax跨域訪問及JQuery的跨域的原理與解決辦法,希望此方法對各位同學有所幫助.JS的跨域問題,我想很多程序員的腦海裏面還認爲JS是不能跨域的,其實這是一
  • JSON這種輕量級的數據交換格式,易于人閱讀和編寫,同時也易于機器解析和生成(網路傳輸速度快),所以在移動開發中應用特別廣範,以前我們講過PHP JSON數據的創建和解析程序代碼,現在我們來講講AJAX 跨域請求 - JSONP獲取JSON數據.相關文章:PHP JSON數據的創建和解析程序代碼JS ...
  • 本文章總結多種關于Iframe跨域訪問不能寫cookie問題的解決辦法,其實我最喜歡的是利用程序來解決,前面的設置站點信任是不可取的哦.假設A嵌套了B解決方法:第一種很簡單:將系統B設置爲可信站點.第二種:IE設置隱
  • 現在浏覽器多但是很多時候標准不一樣兼容性也不好,下面我來介紹解決ff和IE9對icon font字體的跨域訪問不兼容問題,這裏介紹的是apache與nginx的方法.apache解決辦法可以將字體文件放到同域的伺服器上或修改伺服器配置.把如下代碼加到你的伺服器配置文件中去,我用的是apache2,這 ...
  • Session在跨域時都會碰到失效問題了,但是如果我們使用cookie來替換的話就可以方便的解決這個問題哦,下面我們一起來看看利用Cookie替代Session解決跨域Session失效問題方法.分布式系統中,各個子
  • 文章分享一篇關于利用了jquery的ajax 來訪問wcf 伺服器,同時支持GET.POST.PUT.DELETE等常用的訪問方法,後面一個實例介紹了跨域訪問WCF有需要了解的同學可以看看. 代碼如下 using jquery ajax call wcf service get/post/put/d
  • jquery ajax跨域用jsonp方式調用web服務的例子
    ajax跨域對于許多的朋友來講還是用到的比較少了,但在一些大的應用開發時會用到了ajax跨域用jsonp了,下面我們就來看一篇jquery ajax跨域用jsonp方式調用web服務的代碼實例,希望文章能夠幫助到各位朋友.在做一個demo的專案,需要將php,.net的幾個人,加起來一起做個web系 ...
  • 一篇朋友很久前寫的asp.net中WebResponse 跨域訪問示例,下面我轉過來與大家一起學習學習,希望文章對大家會有幫助.前兩天,一個朋友讓我幫他寫這樣一個程序:在asp.net裏面訪問asp的頁面,把數據提交
一周排行