JSONP解释
在解释JSONP之前,我们需要了解下”同源策略“这个概念,这对理解跨域有帮助。基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性。有点绕,说的简单点就是浏览器限制脚本只能和同协议、同域名、同端口的脚本进行交互。
JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议。他允许服务端生成script tags返回值客户端,通过javascript callback的形式来实现站点访问。JSONP是一种script tag的注入,将server返回的response添加到页面是实现特定功能。
简而言之,JSONP本身不是复杂的东西,就是通过scirpt标签对javascript文档的动态解析绕过了浏览器的同源策略。
JSONP原理及实现
接下来,来实际模拟一个跨域请求的解决方案。后端为Spring MVC架构的,前端则通过Ajax进行跨域访问。
1.首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语法的方式,生成一个function
2、接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端。
3、最后客户端浏览器动态的解析script标签,并执行返回的JavaScript语法文档片段,此时数据作为参数传入到了预先定义好的回调函数里(动态执行回调函数)。
SpringMVC端:
1、定义jsonp实体类
class jsonpTest {
private String name ;
public String getName() {
return name ;
}
public void setName(String name) {
this.name = name;
}
}
2、定义Jsonp 工具栏
public class JsonpReturn {
private static final ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.setVisibility(PropertyAccessor. FIELD, Visibility.ANY);
objectMapper.configure(
DeserializationFeature. FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ));
objectMapper.setSerializationInclusion(Include.NON_NULL);
}
/**
* 转换对象为JSON字符串
*
* @param obj
* @return
*/
public static String toJson(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
return null ;
}
}
/**
* 跨域返回数据
* @param callback 指定函数名。
* @param data json数据源
* @return
*/
public static String SUCCESS(String callback, Object data){
String json = callback + "("+JsonpReturn.toJson(data)+ ")";
return json;
}
}
3、关键方法
@RequestMapping("/jsonpTest.do" )
@ResponseBody
public String jsonpTest(HttpServletRequest req,HttpServletResponse res){
String callBack = req.getParameter( "callback");
List<jsonpTest> list = new ArrayList<jsonpTest>();
jsonpTest test = new jsonpTest();
test.setName( "jsonp");
list.add(test);
test = new jsonpTest();
test.setName( "test");
list.add(test);
String json = JsonUtils. toJson(list);
System. out.println(json);
return JsonpReturn.SUCCESS(callBack, list);
}
AJAX 客户端,三种模式:
1、$.ajax:
$.ajax({
url:basePath + "cg_duty/jsonpTest.do",
type: "get",
dataType: "jsonp",
callback: "success_jsonpCallback",
success: function(json){
alert(json.length);
alert($.isArray(json));
alert($.isEmptyObject(json[0]));
},
error: function(){
alert( 'error');
}
});
2、$.getJSON:
$.getJSON(basePath + "cg_duty/jsonpTest.do?callback=?", function(json){
alert(json);
});
3、<script> tag 标签:
<script>
var basePath = '<%= basePath %>';
function jsonpCallback(json){
alert(json);
}
</script>
< script type ="text/javascript"src= "<%= basePath%>cg_duty/jsonpTest.do?callback=jsonpCallback">
</script >
网友评论