1. Jsonp原理介绍
Ajax想必已经是家喻户晓,但是,受制于浏览器的“同源策略”,当需要进行跨越访问时,Ajax就显得有些无能为力。这个时候,我们便需要Jsonp,Jsonp是Json with padding的简称,它是一个非官方协议,允许在服务端继承script tags返回至客户端,通过javascript callback的形式实现跨越访问。
说得更明确一点,就是前端通过JS创建一个script标签,并将src指向请求的url,同时在url中指定回调的callback,而Server端将请求数据转换为json格式(jsonData),将数据填充到callback中并回调callback。
2. 在Spring中支持Jsonp请求
当然了,如果在实际项目中,要考虑方方面面的小细节的处理,但是,作为示例,这里只实现上述的核心流程。借助于之前的一篇文章“Spring MVC自定义视图的实现”,要支持Jsonp的请求,我们只需新增对于JSONP视图的支持,在Jsonp视图的渲染函数中,将需返回的数据转换为json格式,并回调callback即可,当然了callback函数的名称需要前端传入,在Jsonp视图中从request中获得。
JSONP视图的实现如:
- public class JsonpView extends AbstractView {
- protected void renderMergedOutputModel(Map<String, Object> model,
- HttpServletRequest request, HttpServletResponse response) throws Exception {
- //将model中的数据转换为JSON格式
- JSONObject json = (JSONObject)JSONSerializer.toJSON(model);
- //得到JSONP的callback函数名称
- String callback = request.getParameter("callback");
- //将数据填充到callback,并回调
- StringBuffer buf = new StringBuffer();
- buf.append(callback);
- buf.append("(");
- buf.append(json.toString());
- buf.append(");");
- response.setContentType("text/plain; charset=GBK");
- response.getOutputStream().write(buf.toString().getBytes());
- response.getOutputStream().flush();
- }
- }
前端的实现如:
- vote = function(){
- var url = "log/vote.jsonp?callback=" +"voteCallback";
- var script = document.createElement("script");
- script.setAttribute("src",url);
- script.setAttribute("type","text/javascript");
- document.getElementsByTagName("head")[0].appendChild(script);
- };
- voteCallback = function(data){
- alert(data.username+data.password);
- }
当触发vote()函数时,在head中创建一个<script>标签,并将src之前Server端请求url,通知在url中指明callback函数名称,以便服务端可以回调callback函数,同时前端还需实现callback函数,对服务端填充的json数据进行处理,上面示例中只是简单的alert。
而Server端的controller如:
- public String vote(ModelMap model){
- model.addAttribute("username","ds");
- model.addAttribute("password","123456");
- return "vote.jsonp";
- }
最后,spring mvc配置文件如:
- <bean id="multiViewResolver" class="cn.ds.core.service.spring.JmatrixMultiViewResolver">
- <property name="viewMap">
- <map>
- <entry key=".config" value-ref="configView" />
- <entry key=".jsonp" value-ref="jsonpView" />
- </map>
- </property>
- </bean>
- <bean id="jsonpView" class="cn.ds.core.service.spring.JsonpView"></bean>