你知道JSONP的三种跨越模式吗?
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实体类
classjsonpTest{privateString name ;publicStringgetName(){returnname ; }publicvoidsetName(String name){this.name = name; } }
2、定义Jsonp 工具栏
publicclassJsonpReturn{privatestaticfinalObjectMapper objectMapper =newObjectMapper();static{ objectMapper.setVisibility(PropertyAccessor. FIELD, Visibility.ANY); objectMapper.configure( DeserializationFeature. FAIL_ON_UNKNOWN_PROPERTIES,false); objectMapper.setDateFormat(newSimpleDateFormat("yyyy-MM-dd HH:mm:ss")); objectMapper.setSerializationInclusion(Include.NON_NULL); }/** * 转换对象为JSON字符串 * *@paramobj *@return*/publicstaticString toJson(Object obj) {try{returnobjectMapper.writeValueAsString(obj); }catch(Exceptione) { e.printStackTrace();returnnull; } }/** * 跨域返回数据 *@paramcallback 指定函数名。 *@paramdata json数据源 *@return*/publicstaticString SUCCESS(String callback, Object data){ String json = callback +"("+JsonpReturn.toJson(data)+")";returnjson; }}
3、关键方法
@RequestMapping("/jsonpTest.do") @ResponseBodypublicStringjsonpTest(HttpServletRequest req,HttpServletResponse res){ String callBack = req.getParameter("callback"); Listlist=newArrayList(); jsonpTest test =newjsonpTest(); test.setName("jsonp");list.add(test); test =newjsonpTest(); test.setName("test");list.add(test); String json = JsonUtils. toJson(list); System. out.println(json);returnJsonpReturn.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); });