您的位置:首页 > 编程语言 > Java开发

cookie,session专题2-1:springmvc中jsonp跨域的几种解决方案

2016-07-30 09:02 591 查看

方案一:简单的解决方案

方案一原文出自:http://www.cnblogs.com/iqian/p/5062760.html

解决方案技术构架:Ajax+Spring MVC实现跨域请求(JSONP)JSONP 跨域

JSONP原理及实现

接下来,来实际模拟一个跨域请求的解决方案。后端为Spring MVC架构的,前端则通过Ajax进行跨域访问。

1、首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语法的方式,生成一个function

2、接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端。

3、最后客户端浏览器动态的解析script标签,并执行返回的JavaScript语法文档片段,此时数据作为参数传入到了预先定义好的回调函数里(动态执行回调函数)。这种动态解析js文档和eval函数是类似的。

AJAX端:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script>
$(document).ready(function(){

$("#but1").click(function(){
$.ajax({
url:'http://127.0.0.1:8080/DevInfoWeb/get',
type: "get",
async: false,
dataType: "jsonp",
jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数
jsonpCallback: "success_jsonpCallback", //callback的function名称,服务端会把名称和data一起传递回来
success: function(json) {
alert(json);
},
error: function(){alert('Error');}
});
});

$("#but2").click(function(){
$.ajax({
url:'http://127.0.0.1:8080/DevInfoWeb/getJsonp',
type: "get",
async: false,
dataType: "jsonp",
jsonp: "callbackparam", //服务端用于接收callback调用的function名的参数
jsonpCallback: "success_jsonpCallback", //callback的function名称,服务端会把名称和data一起传递回来
success: function(json) {
alert(json);
},
error: function(){alert('Error');}
});
});

});
</script>
</head>
<body>

<div id="div1"><h2>使用 jQuery AJAX 来改变文本</h2></div>
<button id="but1">按钮1</button> <br/>
<button id="but2">按钮2</button>

</body>
</html>

SpringMVC端:


@RequestMapping("/get")
public void get(HttpServletRequest req,HttpServletResponse res) {
res.setContentType("text/plain");
String callbackFunName =req.getParameter("callbackparam");//得到js函数名称
try {
res.getWriter().write(callbackFunName + "([ { name:\"John\"}])"); //返回jsonp数据
} catch (IOException e) {
e.printStackTrace();
}
}

@RequestMapping("/getJsonp")
@ResponseBody
public JSONPObject getJsonp(String callbackparam){
Company company=new Company();
company.setAddress("广州天河华景软件园");
company.setEmail("123456@qq.com");
company.setName("广州讯动网络可以有限公司");
company .setPhone("12345678912");
return new JSONPObject(callbackparam, company);
}

方案二:企业常用的解决方案

使用的jQuery已经提供了解决跨域访问的方案。前端:你只需要在原来的访问地址上加上?callback=?即可。后端:假如前端callback=aaa,springmvc返回时只要用aaa包裹数据即可:aaa("后台返回数据")。

怎样让返回的数据被回调函数名aaa包裹有两种办法可工参考。第一种:自己在返回数据时手动拼接,例如方案一就是手动拼接。第一种手动拼接每次拼接都是固定的拼接步骤,我们要做很多重复而又没有意义的劳动,也使得写出的代码不够简洁。假如写好的代码出现了跨域问题,我们还要重新修改代码逻辑,让程序员修改写好的而又没有错误代码,这无疑是一种折磨。第二种:通过自定义转换器的方式。自己定义一个转换器继承默认的转换器,例如在使用@ResponseBody注解的场景跨域时,可以重写MappingJackson2HttpMessageConverter类,在重写的方法里加上一段逻辑:在请求中判断是否有callback参数名,如果没有直接返回。如果有callback参数名,先拼接好callback回调函数名,再返回。然后再在注解驱动中加上自定义的转换器即可。

关于注解驱动的一些知识可以看个入门介绍:可以看spring的3.2.17版本官方文档17.15.1也可以看

                                                                  http://blog.csdn.net/yfisaboy/article/details/31755631

                                                                  我自己的项目本身使用的Spring MVC 3.2,实际上在3.1之后,

                                                                   <mvc:annotation-driven />注册的类发生了变化

如果想了解多点可以去看看张开涛的博客:http://www.iteye.com/blogs/subjects/kaitao-springmvc

配置SpringMVC返回JSON遇到的坑:http://www.open-open.com/lib/view/open1423128254779.html

我博客所有文章目录:http://blog.csdn.net/wabiaozia?viewmode=contents
-------------------------------------------------------------------------------------------------------------------

当然最准确的定义还是官方文档,学习更多springmvc知识可以参考spring Framework的web部分.

另附spring官方文档https://spring.io/docs/reference

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: