轉載自:http://www.bubuko.com/infodetail-748374.html
跨域,前端開發中經常遇到的問題,AngularJS實現跨域方式類似於Ajax,使用CORS機制。
下面闡述一下AngularJS中使用$http實現跨域請求數據。
AngularJS XMLHttpRequest:$http用於讀取遠程服務器的數據
$http.post(url, data, [config]).success(function(){ ... }); $http.get(url, [config]).success(function(){ ... }); $http.get(url, [config]).success(function(){ ... });
一、$http.jsonp【實現跨域】
1. 指定callback和回調函數名,函數名為JSON_CALLBACK時,會調用success回調函數,JSON_CALLBACK必須全為大寫。
2. 指定其它回調函數,但必須是定義在window下的全局函數。url中必須加上callback。
二、$http.get【實現跨域】
1. 在服務器端設置允許在其他域名下訪問
response.setHeader("Access-Control-Allow-Origin", "*"); //允許所有域名訪問 response.setHeader("Access-Control-Allow-Origin", "http://www.123.com"); //允許www.123.com訪問
2. AngularJS端使用$http.get()
三、$http.post【實現跨域】
1. 在服務器端設置允許在其他域名下訪問,及響應類型、響應頭設置
response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods","POST"); response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type");
2. AngularJS端使用$http.post(),同時設置請求頭信息
$http.post('http://localhost/ajax/getAllIndustryCategoty.pt',{languageColumn:'name_eu'},{'Content-Type':'application/x-www-form-urlencoded'}).success(function(data){ $scope.industries = data; });
四、實現方式
跨域方式一【JSONP】:
方法一:
$http.jsonp("http://localhost/sitesettings/getBadgeInfo.pt?jsonp=JSON_CALLBACK&siteid=137bd406").success(function(data){ ... }); // The name of the callback should be the string JSON_CALLBACK.
方法二【返回值,需要使用對應callback方法接收,但如何置於$scope???】:
$http.jsonp("http://localhost/sitesettings/getBadgeInfo.pt?jsonp=badgeabc&siteid=137bd406"); function badgeabc(data){ ... }
public String execute() throws Exception { String result = FAIL; response.setHeader("", ""); SiteHandlerAction siteHandlerAction = (SiteHandlerAction)BeansFactory.getBean(SiteHandlerAction.class); BadgeHandlerAction badgeHandlerAction = (BadgeHandlerAction)BeansFactory.getBean(BadgeHandlerAction.class); if("".equals(siteid) || siteid == null || StringUtils.isBlank("jsonp")){ result = FAIL; }else{ Site site = siteHandlerAction.find(siteid); UserBadgeStatus userBadgeStatus = badgeHandlerAction.getUserBadgeStatus(site.getId()); if(userBadgeStatus != null){ result = "{\"t\":"+userBadgeStatus.getStyle()+",\"l\":"+userBadgeStatus.getSuspend_location()+",\"s\":"+site.getId()+"}"; JSONObject jsonObj = JSONObject.fromObject(result); String json = jsonObj.toString(); result = jsonp + "(" + json + ")"; } } PrintWriter write = response.getWriter(); write.print(result); write.flush(); write.close(); return NONE; }
跨域方式二【$http.get()】:
function getAdustryController($scope,$http){ $http.get('http://localhost/ajax/getAllIndustryCategoty.pt?languageColumn=name_eu').success(function(data){ $scope.industries = data; }); }
跨域方式三【$http.post()】:
function getAdustryController($scope,$http){ $http.post('http://localhost/ajax/getAllIndustryCategoty.pt',{languageColumn:'name_eu'},{'Content-Type':'application/x-www-form-urlencoded'}).success(function(data){ $scope.industries = data; }); }
// java端支持跨域請求 public String execute(){ response.setHeader("Access-Control-Allow-Origin", "*"); //允許哪些url可以跨域請求到本域 response.setHeader("Access-Control-Allow-Methods","POST"); //允許的請求方法,一般是GET,POST,PUT,DELETE,OPTIONS response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type"); //允許哪些請求頭可以跨域 SiteHandlerAction SiteHandler = (SiteHandlerAction) BeansFactory.getBean(SiteHandlerAction.class); List list = SiteHandler.getAllIndustryCategory(); //所有的分類集合 JSONArray jsonArray = JSONArray.fromObject(list); //將list轉為json String json = jsonArray.toString(); //轉為json字符串 try { PrintWriter write = response.getWriter(); write.print(json); write.close(); } catch (IOException e) { e.printStackTrace(); } return NONE; }
{{ industry.id }} | {{ industry.name_ch }} | {{ industry.name_eu }} | {{ industry.name_jp }} |
轉載自:http://www.bkjia.com/JavaScript/977935.html
大家會自然想到只有一個字母之差的JSON吧~
JSON(JavaScript Object Notation)和JSONP(JSON with Padding)雖然只有一個字母的差別,但其實他們根本不是一回事兒
JSON是一種數據交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域數據交互協議。我們拿最近比較火的諜戰片來打個比方,JSON是地下黨們用來書寫和交換情報的“暗號”,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式。看到沒?一個是描述信息的格式,一個是信息傳遞雙方約定的方法。
瀏覽器是存在同源策略這個機制的,在全局層面禁止了頁面加載或執行與自身來源不同的域的任何腳本。
JSONP是一種可以繞過瀏覽器的安全限制,從不同的域請求數據的方法。
Web頁面上調用js文件時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有”src”這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>);
如果想通過純web端(ActiveX控件、服務端代理、屬於未來的HTML5之Websocket等方式不算)跨域訪問數據就只有一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件里,供客戶端調用和進一步處理;JSON的純字符數據格式可以簡潔的描述復雜數據,被js原生支持,所以在web客戶端通過與調用腳本一模一樣的方式,來調用跨域服務器上動態生成的js格式文件(一般以JSON為后綴),顯而易見,服務器之所以要動態生成JSON文件,目的就在於把客戶端需要的數據裝入進去。為了便於客戶端使用數據,逐漸形成了一種非正式傳輸協議,人們把它稱作JSONP,該協議的一個要點就是允許用戶傳遞一個callback參數給服務端,然后服務端返回數據時會將這個callback參數作為函數名來包裹住JSON數據,這樣客戶端就可以隨意定制自己的函數來自動處理返回數據了。
JSONP的原理是通過<script>標簽發起一個GET請求來取代XHR請求。JSONP生成一個<script>標簽並插到DOM中,然后瀏覽器會接管並向src屬性所指向的地址發送請求。
當服務器返回請求時,響應結果會被包裝成一個JavaScript函數,並由該請求所對應的回調函數調用。
AngularJS在$http服務中提供了一個JSONP輔助函數。通過$http服務的jsonp方法可以發送請求,如下所示:
$http .jsonp("https://api.github.com?callback=JSON_CALLBACK") .success(function(data) {
// 數據
});
當請求被發送時,AngularJS會在DOM中生成一個如下所示的<script>標簽:
<script src="https://api.github.com?callback=angular.callbacks._0" type="text/javascript"></script>
注意,JSON_CALLBACK被替換成了一個特地為此請求生成的自定義函數。當支持JSOPN的服務器返回數據時,數據會被包裝在由AngularJS生成的具名函數angular.callbacks._0中在這個例子中,GitHub服務器會返回包含在回調函數中的JSON數據,響應看起來如下所示:
// 簡寫
angular.callbacks._0({
‘meta‘: {
‘X-RateLimit-Limit‘: ‘60‘,
‘status‘: 200
},
‘data‘: {
‘current_user_url‘: ‘https://api.github.com/user‘
}
})
當AngularJS調用指定的回調函數時會對$http的promise對象進行resolve。當我們自己開發支持JSONP的后端服務時,要確保響應的數據被包含在請求所指定的回調函數中。使用JSONP需要意識到潛在的安全風險。首先,服務器會完全開放,允許后端服務調用應用中的任何JavaScript。不受我們控制的外部站點(或者蓄意攻擊者)可以隨時更改腳本,使我們的整個站點變得脆弱。服務器或中間人有可能會將額外的JavaScript邏輯返回給頁面,從而將用戶的隱私數據暴露出來。由於請求是由<script>標簽發送的,所以只能通過JSONP發送GET請求。並且腳本的異常也很難處理。使用JSONP一定要謹慎,同時只跟信任並可以控制的服務器進行通信。
一句話就是利用script標簽繞過同源策略,獲得一個類似這樣的數據,jsonpcallback是頁面存在的回調方法,參數就是想得到的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); }
angularJS中jsonp的使用
myUrl = "http://localhost:8090/api/testcallback=JSON_CALLBACK"; $http.jsonp(myUrl).success(
function(data){ alert(data); } ); 1.angularJS中使用$http.jsonp函數 2.指定callback和回調函數名,函數名為JSON_CALLBACK時,會調用success回調函數,JSON_CALLBACK必須全為大寫。 3.也可以指定其它回調函數,但必須是定義在window下的全局函數。 4.url中必須加上callback 5.當callback為JSON_CALLBACK時,只會調用success,即使window中有JSON_CALLBACK函數,也不會調用該函數。
轉載自:http://www.bubuko.com/infodetail-748374.html