1、什么是跨域
协议名称和端口号不一样。
2、跨域请求的实现一般方法
1.1 通过代理的方式
在Java代码里面,去访问跨域的请求
1.2 通过动态创建script标签
1. JavaScript代码
<head>
<meta charset="utf-8" />
<title>Ajax的跨域访问</title>
<script type="text/javascript">
//1、用于动态创建script标签的函数
function cerateScript(src) {
var dynScript = document.createElement('script');
dynScript.src = src;
dynScript.setAttribute("type", "text/javascript");
document.getElementsByTagName('head')[0]
.appendChild(dynScript);
}
//2、回调函数,对返回数据的处理
//通过动态标签注入的必须是可执行的JavaScript代码,因此无论是你的数据格式是啥(xml、json等),都必须封装在一个回调函数中。一个回调函数如下:
function dynCallback(data) {
//对返回的数据进行处理
alert(data.age);
}
//3、服务端返回数据的格式,需要将数据封装在上面这个dynCallback函数中,如下:
//dynCallback({age:18})
//4、动态的创建script标签,实现跨域调用
cerateScript("http://localhost:8080/Jsonp/JsonpServlet?callback=dynCallback");
</script>
</head>
2. 后台Servlet代码
public class JsonpServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取回调函数的名称
String callback = request.getParameter("callback");
// 拼接jsonp,用于前端函数的回调
// callback ({"age":"18");
String jsonpResult = callback + "(" + "{ " + "\"age\":\"18\"" + "}"
+ " )";
PrintWriter writer = response.getWriter();
writer.write(jsonpResult);
writer.flush();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
1.3 jquery通过ajax和jsonp来实现跨域
1.前端JavaScript代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Ajax的跨域访问</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
/*jquery不支持post请求的跨域*/
$(function() {
$('#btn').click(function() {
$.ajax({
type: "get",
url: "http://localhost:8080/Jsonp/JsonpServlet",
dataType: "jsonp",
jsonp: "callback", //默认为callback
success: function(data, textStatus) {
alert(data.age);
},
error: function() {
alert('fail');
}
});
});
});
</script>
</head>
<body>
<button id="btn" type="button">点击</button>
</body>
</html>
2.Java的Servlet的代码
public class JsonpServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取回调函数的名称
String callback = request.getParameter("callback");
// 拼接jsonp,用于前端函数的回调
// callback ({"age":"18");
String jsonpResult = callback + "(" + "{ " + "\"age\":\"18\"" + "}"
+ " )";
PrintWriter writer = response.getWriter();
writer.write(jsonpResult);
writer.flush();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
1.4 通过升级版的XmlHttpRequest来实现跨域(正常形似的访问)
1、XMLHttpRequest升级版已经实现了跨域请求。不过需要在后台设置:header("Access-Control-Allow-Origin:http://www.a.com");表示某个域下允许跨域访问。
2、IE:需要使用XDomainRequest()。同样需要在后台设置:response.addHeader("Access-Control-Allow-Origin","*");
3、如果后台语言为java的话,需要自己写一个CrossDomainFilter,在过滤器中设置跨域访问,否则上传不成功。
4、前台代码<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Ajax的跨域访问</title>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript">
/*jquery不支持post请求的跨域*/
$(function() {
$('#btn').click(function() {
$.ajax({
type: "get",
url: "http://127.0.0.1:8080/Jsonp/EnServlet",
success: function(data, textStatus) {
//数据的处理,转换为json对象
var jsonObj = JSON.parse(data);
alert('success');
alert(jsonObj.age);
},
error: function() {
alert('fail');
}
});
});
});
</script>
</head>
<body>
<button id="btn" type="button">点击</button>
</body>
</html>
5、后台代码
public class EnServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String jsonpResult = "{ " + "\"age\":\"18\"" + "}";
PrintWriter writer = response.getWriter();
writer.write(jsonpResult);
writer.flush();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6、过滤器
public class CrossDomainFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) resp;
// 这里最好不要写通配符,如果允许多个域请求数据的话,可以直接用逗号隔开:"http://www.baidu.com,http://google.com"
// 设置允许夸晕访问的主机
res.setHeader("Access-Control-Allow-Origin", "*");
// 设置允许跨域访问的方法
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
// 设置IE浏览器
res.setHeader("Access-Control-Allow-Headers",
"Content-Type, Authorization, Accept,X-Requested-With");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
7、web.xml配置过滤器
<!--配置过滤器 -->
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.jsonp.filter.CrossDomainFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3、代码下载
http://pan.baidu.com/s/1jIpVfmQ
4、参考文章
1、http://kb.cnblogs.com/page/139725/