什么是跨域?
跨域就是跨域名或跨端口号进行调用,只有请求者和被请求者的域名和端口号完全一致,才不是跨域!
例如:
www.baidu.com >> www.jd.com 是跨域
www.baidu.com >> sso.baidu.com 是跨域
www.baidu.com >> www.baidu.com:8080 是跨域
www.baidu.com >> www.baidu.com 不是跨域
什么是跨域问题?
js使用Ajax请求进行跨域请求,无法返回数据(json、xml等)。
为什么会有跨域问题?
浏览器基于安全考虑,不允许Ajax请求跨域调用数据(json、xml等)
我们现在碰到的问题就是,www.baidu.com请求sso.jd.com,因为跨域问题,是无法使用Ajax获取数据的
jsonp核心原理:
js使用Ajax无法跨域调用数据(xml,json等),但是可以跨域调用js数据
案例: js可以跨域
网页访问:http://localhost:8080/Test1/test_portal.jsp
test_portal.jsp内容如下: url
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
$(function() {
$.ajax({
type : "GET",
url : "http://localhost:8082/Test2/sso_js.js",
dataType : "script",
success : function(msg) {
fun(11)
}
});
});
</script>
Test2下的sso_js.js内容如下:
function fun(msg){
alert(msg);
}
结果:
传递json格式时,需要如下操作
test_portal.jsp内容如下: url
<script type="text/javascript" src="js/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
function fun(msg){
alert(msg.a)
}
$(function() {
$.ajax({
type : "GET",
url : "http://localhost:8082/Test2/sso_json.json",
dataType : "script",
success : function(msg) {
}
});
});
</script>
Test下的sso_json.json文件内容
fun({
"a":123
})
结果:
使用jsonp后,路径多出个callback,我们要返回的数据需要被callback的值包括
// 1 获取callback参数
String callback = request.getParameter("callback");
// 2. 判断callback是否为空,
if (StringUtils.isNotBlank(callback)) {
// 如果不为空,表示请示使用的jsonp进行,我们就需要把返回的json数据进行包裹,使用callback
String result = callback + "(" + bool + ")";
return ResponseEntity.ok(result);
案例:定义两个web项目
再Demo1中写一个ajax请求访问Demo2
Demo1得Index,jsp如下
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(function(){
$.post("http://localhost:8080/Demo2/SaveGoodsServlet",
{"id":"1001","name":"aaa"},
function(data){
alert(data);
});
});
</script>
Demo2写一个servlet接收如下
public class SaveGoodsServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
String name = request.getParameter("name");
response.getWriter().write(id+":"+name);
}
访问后报错
Failed to load http://localhost:8080/Demo2/SaveGoodsServlet: No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8180' is therefore not allowed access.
http://localhost:8080/Demo2/SaveGoodsServlet: No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8180' is therefore not allowed access.
当使用ajax访问远程服务器时,请求失败,浏览器报如上错误。这是出于安全的考虑,默认禁止跨域访问导致的
解决方案1:
Demo1中ajax返回得内容格式为"jsonp"如下
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(function(){
$.post("http://localhost:8080/Demo2/SaveGoodsServlet",
{"id":"1001","name":"aaa"},
function(data){
alert(data);
},"jsonp");
});
</script>
"jsonp");
});
</script>
Demo2得servlet的响应值需要用callback包裹如下
public class SaveGoodsServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String id = request.getParameter("id");
String name = request.getParameter("name");
String callback = request.getParameter("callback");
System.out.println(id+"---------------------");
if(callback!=null){
String s = callback+"("+id+")";
response.getWriter().write(s);
}
}
得到的结果