淺析JSONP解決Ajax跨域訪問問題的思路詳解
前幾天,工作上有一新需求,需要前端web頁面異步調(diào)用后臺的Webservice方法返回信息。實現(xiàn)方法有多種,本例采用jQuery+Ajax,完成后,在本地調(diào)試了一切ok,但是部署到服務(wù)器上以后就出現(xiàn)問題了,后臺服務(wù)調(diào)用沒有響應(yīng),怎么回事?代碼沒怎么改動,唯一修改的地方就是jQuery的ajax方法中的url地址。難道是這里的問題,經(jīng)過檢查和調(diào)試,發(fā)現(xiàn)原來是同源策略在作怪,我們知道,JavaScript或jQuery是在Web前端開發(fā)中經(jīng)常使用的動態(tài)腳本技術(shù)。在JavaScript中,有一個很重要的安全性限制,被稱為“Same- Origin Policy”(同源策略)。這一策略對于JavaScript代碼能夠訪問的頁面內(nèi)容做了很重要的限制,即JavaScript只能訪問與包含它的文檔或腳本 在同一域名下的內(nèi)容。不同域名下的腳本不能互相訪問,即便是子域也不行。
但是有時候又不可避免地需要進(jìn)行跨域操作,這時候“同源策略”就是一個限制了,怎么辦呢?采用JSONP跨域GET請求是一個常用的解決方案,下面我們來看一下JSONP跨域是如何實現(xiàn)的,并探討下JSONP跨域的原理。
這里提到了JSONP,那有人就問了,它同JSON有什么區(qū)別不同和區(qū)別呢,接下我們就來看看,百度百科有以下說明:
JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。 JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的數(shù)據(jù)交換語言。易于人閱讀和編寫,同時也易于機(jī)器解析和生成(網(wǎng)絡(luò)傳輸速度快)。
JSONP(JSON with Padding)是JSON的 一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。由于同源策略,一般來說位于 server1.example.com 的網(wǎng)頁無法與不是 server1.example.com的服務(wù)器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料并不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執(zhí)行而不是用 JSON 解析器解析。
到這里,應(yīng)該明白了,JSON是一種輕量級的數(shù)據(jù)交換格式,像xml一樣,是用來描述數(shù)據(jù)間的。JSONP是一種使用JSON數(shù)據(jù)的方式,返回的不是JSON對象,是包含JSON對象的javaScript腳本。
那JSONP是如何工作的呢,我們知道,由于同源策略的限制,XmlHttpRequest只允許請求當(dāng)前源(域名、協(xié)議、端口)的資源。若要跨域請求出于安全性考慮是不行的,但是我們發(fā)現(xiàn),Web頁面上調(diào)用js文件時則不受是否跨域的影響,而且擁有”src”這個屬性的標(biāo)簽都擁有跨域的能力,比如<script>、<img>、<iframe>,這時候,聰明的程序猿就想到了變通的方法,如果要進(jìn)行跨域請求, 通過使用html的script標(biāo)記來進(jìn)行跨域請求,并在響應(yīng)中返回要執(zhí)行的script代碼,其中可以直接使用JSON傳遞 javascript對象。即在跨域的服務(wù)端生成JSON數(shù)據(jù),然后包裝成script腳本回傳,這不就突破同源策略的限制,解決了跨域訪問的問題了么。
下面我們就看下怎么實現(xiàn):
前端代碼:
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(); //上面代碼必須 //中間代碼執(zhí)行自己的業(yè)務(wù)操作,可返回自己的任意信息(多數(shù)據(jù)類型) 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方法調(diào)用后端的Web服務(wù)GetSingleInfo方法,后臺的GetSingleInfo方法,使用前端的回調(diào)方法OnGetMemberSuccessByjsonp包裝后臺的業(yè)務(wù)操作的JSON對象,返回給前端一段javascript片段執(zhí)行。巧妙的解決了跨域訪問問題。
JSONP的缺點:
JSONP不提供錯誤處理。如果動態(tài)插入的代碼正常運行,你可以得到返回,但是如果失敗了,那么什么都不會發(fā)生。
以上內(nèi)容簡單給大家介紹了JSONP解決Ajax跨域訪問問題的思路,希望能夠幫助到大家,如果大家有疑問歡迎給我留言,小編會及時回復(fù)大家的,在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
ajax中的async屬性值之同步和異步及同步和異步區(qū)別
在Jquery中ajax方法中async用于控制同步和異步,當(dāng)async值為true時是異步請求,當(dāng)async值為fase時是同步請求。ajax中async這個屬性,用于控制請求數(shù)據(jù)的方式,默認(rèn)是true,即默認(rèn)以異步的方式請求數(shù)據(jù)。2015-10-10使用ajax技術(shù)無刷新動態(tài)調(diào)用新浪股票實時數(shù)據(jù)
由于最近網(wǎng)速慢的緣故,查看股票信息時網(wǎng)頁老是打不開。這幾天一直在研究ajax,于是用jquery自己做了一個自動讀取新浪股票實時數(shù)據(jù)的頁面2014-08-08ajax請求攜帶自定義請求頭header(跨域和同域)案例實戰(zhàn)教程
這篇文章主要介紹了ajax請求攜帶自定義請求頭header(跨域和同域)案例實戰(zhàn)教程,ajax請求是有同源策略的,雖然可以應(yīng)用CORS等手段來實現(xiàn)跨域,但是這并不是說這樣就是“同源”了,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10不使用XMLHttpRequest對象實現(xiàn)Ajax效果的方法小結(jié)
這篇文章主要介紹了不使用XMLHttpRequest對象實現(xiàn)Ajax效果的方法,結(jié)合具體實例形式分析了三種不使用XMLHttpRequest對象實現(xiàn)Ajax功能的相關(guān)實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下2019-07-07jQuery通過Ajax向PHP服務(wù)端發(fā)送請求并返回JSON數(shù)據(jù)
這篇文章主要介紹了jQuery通過Ajax向PHP服務(wù)端發(fā)送請求并返回JSON數(shù)據(jù),設(shè)計到的知識點有jquery、ajax、php、json,感興趣的朋友一起學(xué)習(xí)下jquery ajax 返回json2015-10-10JavaScript基于Ajax實現(xiàn)不刷新在網(wǎng)頁上動態(tài)顯示文件內(nèi)容
這篇文章主要介紹了JavaScript基于Ajax實現(xiàn)不刷新在網(wǎng)頁上動態(tài)顯示文件內(nèi)容,可實現(xiàn)實時顯示服務(wù)器上txt文件內(nèi)容的功能,是Ajax基本應(yīng)用,具有一定參考借鑒價值,需要的朋友可以參考下2015-03-03Ajax讀取數(shù)據(jù)到表格的實現(xiàn)代碼
前兩篇我們講了"ajax開始的準(zhǔn)備"與及如何使用ajax技術(shù)進(jìn)行簡單的數(shù)據(jù)讀取.今天我們要講的是:使用Ajax無刷新技術(shù)讀取服務(wù)端多條數(shù)據(jù),并將返回的數(shù)據(jù)顯示到一個表格內(nèi).2010-08-08