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 list =
new
ArrayList();
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);
});