在移动App、移动网站或者PC Web网站中,经常会遇到Ajax跨域到后台获取数据。今天给大家介绍在Angular.js中如何通过$http.jsonp跨域到Java后台Servlet中获取数据。
一、同源策略
在web页面的开发中我们经常会说起脚本的跨域访问的问题,这个问题的始作俑者就是javascript语言安全限制中的同源策略(same-origin policy )所造成的。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。
所谓同源是指,域名,协议,端口相同,同源策略简单的说就是一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合。
示例:来自http://www.bchy.cn/a/b.html的js脚本访问下列url的结果和原因。
URL | 结果 | 原因 |
成功 |
| |
成功 |
| |
失败 | 协议不同 | |
失败 | 端口不同 | |
失败 | 主机名不同 |
二、比较JSON和JSONP
JSON和JSONP是完全不一样的,首先JSON是众多数据存储格式中的一种。JSONP是一种特殊的通讯方式,使用它能够轻松绕过浏览器的同源安全限制,达到加载来自不同源的资源(脚本, 图片, 其他)的效果,实现跨域。
需要注意的是,使用JSOPN有潜在的安全隐患,因为JSONP允许后端服务调用应用的JavaScript,使站点变得脆弱的同时,还可能暴露用户隐私。
三、具体实现
1、客户端:
$http.jsonp(url+"?callback=JSON_CALLBACK").success(function(data){});其中url是服务端的地址,data是服务端发给客户端的数据。
例如:
$http.jsonp("http://192.168.1.101:8080/HungryServer/GetAllServlet?callback=JSON_CALLBACK").success(function(data){
$scope.foods=data;
}).error(function(data){
alert("error"+data);
}).finally(function(){
alert("finally");
});
2、服务端
public class GetAllServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException, IOException {
String callback=request.getParameter("callback");
/**
*编写从后台获取数据的代码,一般是数组或者键值对集合。
*其中的jsonData是从后台获取数据。
**/
response.setContentType("text/html; charset=utf-8");
PrintWriterout=response.getWriter();
out.print(callback+"("+jsonData+");");
out.flush();
out.close();
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException, IOException {
doGet(request, response);
}
}