解析AngularJS中g(shù)et請求URL出現(xiàn)的跨域問題
今天早上幫助同學(xué)看了一個AngularJS的問題,主要是請求中出現(xiàn)了跨域訪問,請求被阻止。
下面是她給我的代碼:
<html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Title</title> <!--<script src="../js/jquery-1.11.0.js"></script>--> <script src="angular.min.js"></script> <script> angular.module("myApp",[]).controller("test",["$scope","$http",function($scope,$http){ $http.get("http://datainfo.duapp.com/shopdata/getGoods.php?classID=1") .success(function(response){ $scope.myarr = response.sites; }) }]) </script> </head> <body> <div ng-controller="test"> <ul> <li ng-repeat="data in myarr"> <img src="{{data.goodsListImg}}"/> <p>名稱:<span>{{data.goodsName}}</span></p> <p>價格:<span>{{data.price|currency:"¥"}}</span></p> </li> </ul> </div> </body> </html>
出現(xiàn)的問題
我們可以看到他是通過$http的get方式訪問URL,一直訪問不了,我將具體的response打印到控制臺上面,也使出現(xiàn)了問題。
這個是瀏覽器的跨域造成的,之前的學(xué)習(xí)中我也不是很清楚這個,只是知道由于不是在同一個域名下面訪問的此域名下的資源就會造成跨域。其實之前看到這個是以為請求的格式有問題,返回的json數(shù)據(jù)到不了。
下面是json格式返回的數(shù)據(jù)。
按照她給我的URL,我發(fā)現(xiàn)在json數(shù)據(jù)前面有一個callback,這個是php中的回調(diào)函數(shù),結(jié)果網(wǎng)上一搜發(fā)現(xiàn)get請求對于這種回調(diào)函數(shù)是沒有作用的。
解決辦法
必須使用下面的這種辦法來處理這種有callback的jsonp格式的數(shù)據(jù)。
<script> var myApp = angular.module("App", []); myApp.controller("test", function($scope, $http) { // 回調(diào)函數(shù)用法 myUrl = "http://datainfo.duapp.com/shopdata/getGoods.php?callback=JSON_CALLBACK"; $http.jsonp(myUrl).success(function(response) { console.log(response); }); }); </script>
注意兩點:
- 使用$http.jsonp()請求數(shù)據(jù);(解決了跨域的問題)
- 在URL后面添加callback=JSON_CALLBACK字符;
這樣就可以正常的訪問數(shù)據(jù)。其實對于json個格式的數(shù)據(jù)我們要是想知道那里有錯誤,有一種辦法是將其打印到瀏覽器的控制臺中,這樣我們就可以看到具體的流程和結(jié)果。
完整代碼
<!DOCTYPE html> <html ng-app="App"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="angular.min.js"></script> <script> var myApp = angular.module("App", []); myApp.controller("test", function($scope, $http) { // 回調(diào)函數(shù)用法 myUrl = "http://datainfo.duapp.com/shopdata/getGoods.php?callback=JSON_CALLBACK"; $http.jsonp(myUrl).success(function(response) { console.log(response); $scope.myarr = response; }); }); </script> </head> <body> <div ng-controller="test"> <ul> <li ng-repeat="data in myarr"> <!--scr里面的angularJS不可以這樣寫--> <img src="{{data.goodsListImg}}" /> <p>名稱:<span>{{data.goodsName}}</span></p> <p>價格:<span>{{data.price|currency:"¥"}}</span></p> </li> </ul> </div> </body>
自動將我們的JSON_CALLBACK替換成了下面的字符,這應(yīng)該是AngularJS替換的。
引用
跨域是如何解決的:
通過json來傳遞數(shù)據(jù),靠jsonp來跨域,json是一種數(shù)據(jù)交換格式,而jsonp是一種靠開發(fā)人員的聰明才智創(chuàng)造的一種非官方跨域數(shù)據(jù)交互協(xié)議;
JSONP是如何產(chǎn)生的:
- 一個眾所周知的問題,Ajax直接請求普通文件存在跨域無權(quán)限訪問的問題,甭管你是靜態(tài)頁面、動態(tài)網(wǎng)頁、web服務(wù)、WCF,只要是跨域請求,一律不準(zhǔn);
- 不過我們又發(fā)現(xiàn),Web頁面上調(diào)用js文件時則不受是否跨域的影響(不僅如此,我們還發(fā)現(xiàn)凡是擁有”src”這個屬性的標(biāo)簽都擁有跨域的能力,比如<script>、<img>、<iframe>);
- 于是可以判斷,當(dāng)前階段如果想通過純web端(ActiveX控件、服務(wù)端代理、屬于未來的HTML5之Websocket等方式不算)跨域訪問數(shù)據(jù)就只有一種可能,那就是在遠(yuǎn)程服務(wù)器上設(shè)法把數(shù)據(jù)裝進(jìn)js格式的文件里,供客戶端調(diào)用和進(jìn)一步處理;
- 恰巧我們已經(jīng)知道有一種叫做JSON的純字符數(shù)據(jù)格式可以簡潔的描述復(fù)雜數(shù)據(jù),更妙的是JSON還被js原生支持,所以在客戶端幾乎可以隨心所欲的處理這種格式的數(shù)據(jù);
- 這樣子解決方案就呼之欲出了,web客戶端通過與調(diào)用腳本一模一樣的方式,來調(diào)用跨域服務(wù)器上動態(tài)生成的js格式文件(一般以JSON為后綴),顯而易見,服務(wù)器之所以要動態(tài)生成JSON文件,目的就在于把客戶端需要的數(shù)據(jù)裝入進(jìn)去。
- 客戶端在對JSON文件調(diào)用成功之后,也就獲得了自己所需的數(shù)據(jù),剩下的就是按照自己需求進(jìn)行處理和展現(xiàn)了,這種獲取遠(yuǎn)程數(shù)據(jù)的方式看起來非常像AJAX,但其實并不一樣。
- 為了便于客戶端使用數(shù)據(jù),逐漸形成了一種非正式傳輸協(xié)議,人們把它稱作JSONP,該協(xié)議的一個要點就是允許用戶傳遞一個callback參數(shù)給服務(wù)端,然后服務(wù)端返回數(shù)據(jù)時會將這個callback參數(shù)作為函數(shù)名來包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來自動處理返回數(shù)據(jù)了。
AngularJS中處理jsonp數(shù)據(jù)
- 使用$http.jsonp()函數(shù)來發(fā)送請求;
- 指定callback和回調(diào)函數(shù)名,函數(shù)名為JSON_CALLBACK時,會回調(diào)success函數(shù),JSON_CALLBACK必須全部大寫;
- 也可以指定其它回調(diào)函數(shù),但必須定義在window下的全局函數(shù);
- URL中必須添加callback;
瀏覽器是存在同源策略的,在全局層面禁止了頁面加載或執(zhí)行與自身來源不同的域的任何腳本;JSONP是一種可以繞過瀏覽器的安全限制,從不同的域請求數(shù)據(jù)的方法;
這個解釋足以理解跨域問題和為什么需要使用JSONP?
以上就是本文的全部內(nèi)容,希望對大家有所幫助,同時也希望多多支持腳本之家!
相關(guān)文章
angularjs $http實現(xiàn)form表單提交示例
這篇文章主要介紹了angularjs $http實現(xiàn)form表單提交示例,非常具有實用價值,需要的朋友可以參考下2017-06-06深入淺析angular和vue還有jquery的區(qū)別
vue是一個漸進(jìn)式的框架, 是一個輕量級的框架而angular是一個mvc框架, 各有千秋,下面小編通過本文給大家介紹angular和vue還有jquery的區(qū)別,感興趣的朋友一起看看吧2018-08-08解決三元運算符 報錯“SyntaxError: can''''t assign to conditional expre
在本篇文章里小編給大家整理的是關(guān)于python三元運算符 報錯“SyntaxError: can't assign to conditional expression”的處理方法,需要的朋友們學(xué)習(xí)下。2020-02-02Angularjs實現(xiàn)控制器之間通信方式實例總結(jié)
這篇文章主要介紹了Angularjs實現(xiàn)控制器之間通信方式,結(jié)合實例形式總結(jié)分析了AngularJS控制器常用通信方式及相關(guān)操作注意事項,需要的朋友可以參考下2018-03-03AngularJs html compiler詳解及示例代碼
本文主要介紹AngularJs html compiler的知識講解,這里整理了相關(guān)資料及相關(guān)示例代碼,有興趣的小伙伴可以參考下2016-09-09AngularJS中directive指令使用之事件綁定與指令交互用法示例
這篇文章主要介紹了AngularJS中directive指令使用之事件綁定與指令交互用法,結(jié)合實例形式分析了directive指令在模板的使用,事件的綁定及元素、屬性、控制器之間的交互相關(guān)操作技巧,需要的朋友可以參考下2016-11-11