JavaScript规范中提到的json是不能直接跨域调用,为了安全,但是能调用js片段,所以把json包装为一个js片段,也就是jsonp,那么就能够跨域请求。
假设我们原来的JSON数据为
{"hello":"你好","veryGood":"很好"}
那么对应的JSONP的格式就是
functionName({"hello":"你好","veryGood":"很好"})
其中”functionName”不是固定值,自己定义。
在SpringMVC中实现支持JSONP总结为如下几点:
1.response 响应类型为application/javascript
2.进行json请求的URL中需要携带参数 jsonp 或 callback,并指定值。
如 http://mydomain/index.jsonp?callback=myfun
或 http://mydomain/index.jsonp?jsonp=myfun
其中 myfun 就为最终包裹在原有JSON外的函数名
3.如果你在配置文件中配置过MappingJacksonJsonView
,那么请修改使用MappingJackson2JsonView
4.Controller 中的方法需要返回ModelAndView
或者未使用@ResponseBody
注解的返回 String 页面。也就是说最终怎么呈现结果,交由SpringMVC来给我们完成。
5.针对显式注解@ResponseBody
的方法 (我们本来就是直接响应JSON的),我们需要做特殊处理,使用MappingJacksonValue
进行封装处理。
前端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#b1").click(function(){
$.ajax({
url:'http://localhost:8080/myjsonp/testJson.json?name=Shanhy&name1=Lily',
type: "get",
async: false,
dataType: "jsonp",
jsonp: "callback", //服务端用于接收callback调用的function名的参数(请使用callback或jsonp)
jsonpCallback: "fun_jsonpCallback", //callback的function名称
success: function(json) {
alert(json.name);
},
error: function(){
alert('Request Error');
}
});
});
$("#b2").click(function(){
$.ajax({
url:'http://localhost:8080/myjsonp/testJson.json?name=Shanhy&name1=Lily',
type: "get",
async: false,
//dataType: "jsonp",
//jsonp: "callback", //服务端用于接收callback调用的function名的参数(请使用callback或jsonp)
//jsonpCallback: "fun_jsonpCallback", //callback的function名称
success: function(json) {
alert(json.name1);
},
error: function(){
alert('Request Error');
}
});
});
});
</script>
</head>
<body>
<div id="div1"><h2>jQuery AJAX 的跨域请求</h2></div>
<button id="b1">JSONP请求 (预期结果为成功)</button> <br/>
<button id="b2">JSON请求 (预期结果为失败)</button>
</body>
</html>
Controller
@RequestMapping(value="/myjsonp/testJson")
@ResponseBody
public Object list(String name, String name1, String callback) {
Map<String, Object> result = new HashMap<String, Object>();
result.put("name", name);
result.put("name1", name1);
if (StringUtils.isBlank(callback)) {
//需要把result转换成字符串
return result;
}
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}