跨域的原理
浏览器的同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。
一般的,只要网站的 协议名protocol、 主机host、 端口号port 这三个中的任意一个不同,网站间的数据请求与传输便构成了跨域调用。
利用jsonp实现跨域访问
我使用两台电脑模拟来模拟
第一台的服务器:
http://192.168.2.104:8089/testJSOP
此地址用来返回数据
springmvc框架,简单的代码如下
@ResponseBody
@RequestMapping("/testJSOP")
public String testJSONP(String callback){
JSONObject result = new JSONObject();//用的是阿里的fastjson
result.put("aa",1);
result.put("bb", 2);
return callback+"("+result.toString()+")";
}
第二台服务器:
此机器只有一个服务页面,向上面的服务器请求获取数据
http://192.168.2.122:8085/index.jsp
-
使用 jQuery 集成的 $.ajax 实现 JSONP 跨域调用
在此页面http://192.168.2.122:8085/index.jsp
编写如下内容:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<div id="_div"></div>
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
//function dohandle(data){//用$.ajax的话,可以不写此函数
// $("#_div").text(data.aa+"---"+data.bb);
//}
$.ajax({
type:"POST",
url:"http://192.168.2.104:8089/testJSOP",
dataType:"jsonp",
data:{param1:1},
// jsonp 字段含义为服务器通过什么字段获取回调函数的名称
//相当于一个参数
jsonp:'callback',
//回调函数的名称
jsonpCallback:'dohandle',
success:function(data){
console.info(data);
$("#_div").text(data.aa+"---"+data.bb);
}
});
</script>
</body>
</html>
-
使用
<script>
标签原生实现 JSONP
由于实现的原理不同,由 JSONP 实现的跨域调用不是通过 XmlHttpRequset 对象,而是通过 script
标签,所以在实现原理上,JSONP 和 Ajax 已经一点关系都没有了。看上去形式相似只是由于 jQuery 对 JSONP 做了封装和转换
添加新页面http://192.168.2.122:8085/index2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<div id="_div"></div>
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
function dohandle(data){
$("#_div").text(data.aa+"---"+data.bb);
}
var jsonpScript = '<script type="text/javascript" src="http://192.168.2.104:8089/testJSOP?param1=2&callback=dohandle"><\/script>';
$("head").append(jsonpScript);
</script>
</body>
</html>
使用 CORS 实现跨域调用
Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。与 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。用 CORS 可以让网页设计师用一般的 XMLHttpRequest,这种方式的错误处理比 JSONP 要来的好。另一方面,JSONP 可以在不支持 CORS 的老旧浏览器上运作。现代的浏览器都支持 CORS。
第一台服务器:
http://192.168.2.104:8089/testJSOP
此地址用来返回数据
springmvc框架,简单的代码如下
@ResponseBody
@RequestMapping("/testJSOP")
public String testJSONP(HttpServletResponse res){
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Headers", "X-Requested-With");
res.addHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
JSONObject result = new JSONObject();
result.put("aa",1);
result.put("bb", 2);
return result.toString();
}
第二台服务器
http://192.168.2.122:8085/index3.jsp
页面内容:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<div id="_div"></div>
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$.ajax({
type:"POST",
url:"http://192.168.2.104:8089/testJSOP",
dataType:"json",
cache:false,
data:{param1:1},
success:function(data){
console.info(data);
$("#_div").text(data.aa+"---"+data.bb);
}
});
</script>
</body>
</html>