AngularJS實(shí)現(xiàn)的JSONP跨域訪問(wèn)數(shù)據(jù)傳輸功能詳解
本文實(shí)例講述了AngularJS實(shí)現(xiàn)的JSONP跨域訪問(wèn)數(shù)據(jù)傳輸功能。分享給大家供大家參考,具體如下:
大家會(huì)自然想到只有一個(gè)字母之差的JSON吧~
JSON(JavaScript Object Notation)和JSONP(JSON with Padding)雖然只有一個(gè)字母的差別,但其實(shí)他們根本不是一回事兒
JSON是一種數(shù)據(jù)交換格式,而JSONP是一種依靠開(kāi)發(fā)人員的聰明才智創(chuàng)造出的一種非官方跨域數(shù)據(jù)交互協(xié)議。我們拿最近比較火的諜戰(zhàn)片來(lái)打個(gè)比方,JSON是地下黨們用來(lái)書寫和交換情報(bào)的“暗號(hào)”,而JSONP則是把用暗號(hào)書寫的情報(bào)傳遞給自己同志時(shí)使用的接頭方式??吹?jīng)]?一個(gè)是描述信息的格式,一個(gè)是信息傳遞雙方約定的方法。
瀏覽器是存在同源策略這個(gè)機(jī)制的,在全局層面禁止了頁(yè)面加載或執(zhí)行與自身來(lái)源不同的域的任何腳本。
JSONP是一種可以繞過(guò)瀏覽器的安全限制,從不同的域請(qǐng)求數(shù)據(jù)的方法。
Web頁(yè)面上調(diào)用js文件時(shí)則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有”src”這個(gè)屬性的標(biāo)簽都擁有跨域的能力,比如<script>、<img>、<iframe>);
如果想通過(guò)純web端(ActiveX控件、服務(wù)端代理、屬于未來(lái)的HTML5之Websocket等方式不算)跨域訪問(wèn)數(shù)據(jù)就只有一種可能,那就是在遠(yuǎn)程服務(wù)器上設(shè)法把數(shù)據(jù)裝進(jìn)js格式的文件里,供客戶端調(diào)用和進(jìn)一步處理;JSON的純字符數(shù)據(jù)格式可以簡(jiǎn)潔的描述復(fù)雜數(shù)據(jù),被js原生支持,所以在web客戶端通過(guò)與調(diào)用腳本一模一樣的方式,來(lái)調(diào)用跨域服務(wù)器上動(dòng)態(tài)生成的js格式文件(一般以JSON為后綴),顯而易見(jiàn),服務(wù)器之所以要?jiǎng)討B(tài)生成JSON文件,目的就在于把客戶端需要的數(shù)據(jù)裝入進(jìn)去。為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP,該協(xié)議的一個(gè)要點(diǎn)就是允許用戶傳遞一個(gè)callback參數(shù)給服務(wù)端,然后服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名來(lái)包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來(lái)自動(dòng)處理返回?cái)?shù)據(jù)了。
JSONP的原理是通過(guò)<script>標(biāo)簽發(fā)起一個(gè)GET請(qǐng)求來(lái)取代XHR請(qǐng)求。JSONP生成一個(gè)<script>標(biāo)簽并插到DOM中,然后瀏覽器會(huì)接管并向src屬性所指向的地址發(fā)送請(qǐng)求。
當(dāng)服務(wù)器返回請(qǐng)求時(shí),響應(yīng)結(jié)果會(huì)被包裝成一個(gè)JavaScript函數(shù),并由該請(qǐng)求所對(duì)應(yīng)的回調(diào)函數(shù)調(diào)用。
AngularJS在http服務(wù)中提供了一個(gè)JSONP輔助函數(shù)。通過(guò)http服務(wù)中提供了一個(gè)JSONP輔助函數(shù)。通過(guò)http服務(wù)的jsonp方法可以發(fā)送請(qǐng)求,如下所示:
$http .jsonp("https://api.github.com?callback=JSON_CALLBACK") .success(function(data) {
// 數(shù)據(jù)
});
當(dāng)請(qǐng)求被發(fā)送時(shí),AngularJS會(huì)在DOM中生成一個(gè)如下所示的<script>標(biāo)簽:
<script src="https://api.github.com?callback=angular.callbacks._0" type="text/javascript"></script>
注意,JSON_CALLBACK被替換成了一個(gè)特地為此請(qǐng)求生成的自定義函數(shù)。當(dāng)支持JSOPN的服務(wù)器返回?cái)?shù)據(jù)時(shí),數(shù)據(jù)會(huì)被包裝在由AngularJS生成的具名函數(shù)angular.callbacks._0中在這個(gè)例子中,GitHub服務(wù)器會(huì)返回包含在回調(diào)函數(shù)中的JSON數(shù)據(jù),響應(yīng)看起來(lái)如下所示:
// 簡(jiǎn)寫
angular.callbacks._0({
'meta': {
'X-RateLimit-Limit': '60',
'status': 200
},
'data': {
'current_user_url': 'https://api.github.com/user'
}
})
當(dāng)AngularJS調(diào)用指定的回調(diào)函數(shù)時(shí)會(huì)對(duì)$http的promise對(duì)象進(jìn)行resolve。當(dāng)我們自己開(kāi)發(fā)支持JSONP的后端服務(wù)時(shí),要確保響應(yīng)的數(shù)據(jù)被包含在請(qǐng)求所指定的回調(diào)函數(shù)中。使用JSONP需要意識(shí)到潛在的安全風(fēng)險(xiǎn)。首先,服務(wù)器會(huì)完全開(kāi)放,允許后端服務(wù)調(diào)用應(yīng)用中的任何JavaScript。不受我們控制的外部站點(diǎn)(或者蓄意攻擊者)可以隨時(shí)更改腳本,使我們的整個(gè)站點(diǎn)變得脆弱。服務(wù)器或中間人有可能會(huì)將額外的JavaScript邏輯返回給頁(yè)面,從而將用戶的隱私數(shù)據(jù)暴露出來(lái)。由于請(qǐng)求是由<script>標(biāo)簽發(fā)送的,所以只能通過(guò)JSONP發(fā)送GET請(qǐng)求。并且腳本的異常也很難處理。使用JSONP一定要謹(jǐn)慎,同時(shí)只跟信任并可以控制的服務(wù)器進(jìn)行通信。
一句話就是利用script標(biāo)簽繞過(guò)同源策略,獲得一個(gè)類似這樣的數(shù)據(jù),jsonpcallback是頁(yè)面存在的回調(diào)方法,參數(shù)就是想得到的json。
Jquery中jsonp的使用
myUrl = "http://localhost:8090/api/test";
$.ajax({
type:"GET",
url:myUrl,
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"jsonpCallback",
success:function(data){
alert(data.msg);
}
});
function jsonpCallback(data){
alert(data);
}
1.jsonp只能使用get請(qǐng)求,解決同源問(wèn)題,返回javascript代碼,因?yàn)檎?qǐng)求javascript文件是沒(méi)有同源問(wèn)題的。
2.當(dāng)請(qǐng)求數(shù)據(jù)類型為jsonp時(shí),會(huì)將callback=jsonpCallback加在url上,http://localhost:8090/api/testcallback=jsonpCallback
3.前臺(tái)javascript中定義jsonpCallback函數(shù),此函數(shù)必須定義在window下,也就是全局的函數(shù),否則找不到。
4.后臺(tái)獲取請(qǐng)求的callback參數(shù)值jsonpCallback,返回字符串"jsonpCallback(result)",result為返回結(jié)果。
5.請(qǐng)求返回的是script tag,首先會(huì)調(diào)用jsonpCallback函數(shù),不管是否找到該函數(shù),都會(huì)調(diào)用success函數(shù)。
6.如果沒(méi)有定義jsonp和jsonpCallback,jsonp默認(rèn)為"callback",jsonpCallback會(huì)是Jquery自動(dòng)生成的函數(shù)名。
angularJS中jsonp的使用
myUrl = "http://localhost:8090/api/test?callback=JSON_CALLBACK";
$http.jsonp(myUrl).success(
function(data){
alert(data);
}
);
1.angularJS中使用$http.jsonp函數(shù)
2.指定callback和回調(diào)函數(shù)名,函數(shù)名為JSON_CALLBACK時(shí),會(huì)調(diào)用success回調(diào)函數(shù),JSON_CALLBACK必須全為大寫。
3.也可以指定其它回調(diào)函數(shù),但必須是定義在window下的全局函數(shù)。
4.url中必須加上callback
5.當(dāng)callback為JSON_CALLBACK時(shí),只會(huì)調(diào)用success,即使window中有JSON_CALLBACK函數(shù),也不會(huì)調(diào)用該函數(shù)。
更多關(guān)于AngularJS相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《AngularJS指令操作技巧總結(jié)》、《AngularJS入門與進(jìn)階教程》及《AngularJS MVC架構(gòu)總結(jié)》
希望本文所述對(duì)大家AngularJS程序設(shè)計(jì)有所幫助。
相關(guān)文章
AngularJs實(shí)現(xiàn)ng1.3+表單驗(yàn)證
這篇文章主要介紹了AngularJs實(shí)現(xiàn)ng1.3+表單驗(yàn)證,感興趣的小伙伴們可以參考一下2015-12-12
AngularJS控制器controller正確的通信的方法
AngularJS中的controller是個(gè)函數(shù),用來(lái)向視圖的作用域($scope)添加額外的功能,我們用它來(lái)給作用域?qū)ο笤O(shè)置初始狀態(tài),并添加自定義行為2016-01-01
Angular directive遞歸實(shí)現(xiàn)目錄樹結(jié)構(gòu)代碼實(shí)例
本篇文章主要介紹了Angular directive遞歸實(shí)現(xiàn)目錄樹結(jié)構(gòu)代碼實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
AngularJS監(jiān)聽(tīng)ng-repeat渲染完成的兩種方法
這篇文章主要介紹了AngularJS監(jiān)聽(tīng)ng-repeat渲染完成的兩種方法,結(jié)合實(shí)例形式分析了AngularJS基于自定義指令及廣播事件實(shí)現(xiàn)監(jiān)聽(tīng)功能的相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
Angular跨字段驗(yàn)證器中如何直接調(diào)用其它獨(dú)立的驗(yàn)證器
我們?cè)陂_(kāi)發(fā)的時(shí)候都會(huì)用到表單,那么驗(yàn)證器就是必不可少的東西,這篇文章主要給大家介紹了關(guān)于在Angular跨字段驗(yàn)證器中如何直接調(diào)用其它獨(dú)立的驗(yàn)證器的相關(guān)資料,需要的朋友可以參考下2022-03-03
使用AngularJS編寫多選按鈕選中時(shí)觸發(fā)指定方法的指令代碼詳解
最近做項(xiàng)目時(shí)遇到了需要用到多選按鈕選中觸發(fā)事件的功能,小編試著手寫一個(gè)指令,具體實(shí)現(xiàn)代碼大家參考下本文吧2017-07-07
AngularJs用戶輸入動(dòng)態(tài)模板XSS攻擊示例詳解
這篇文章主要給大家介紹了關(guān)于AngularJs用戶輸入動(dòng)態(tài)模板XSS攻擊的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用angularjs具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-04-04
Angular實(shí)現(xiàn)下載安裝包的功能代碼分享
本文通過(guò)實(shí)例代碼給大家介紹了angular實(shí)現(xiàn)下載安裝包的功能以及基于angularjs代碼實(shí)現(xiàn)錨點(diǎn)跳轉(zhuǎn)的功能,需要的朋友參考下吧2017-09-09

