项目开发中,某个可独立、也可集成的子业务模块需要向外开放相关API接口,先说下项目自己使用了jersery来实现RESTful webservice以名词形式公布API。有意思的是在实际的操做中同事却经过Ajax跨域请求的方式去调用该API,先不说成功与否,这样的方式本就是“滑稽"的。和他一块儿探讨了此种作法的不合理性,以后选择jersey client的方式进行远程调用。只是他在跨域请求中遇到了问题,本身闲暇时间予以解决,这才是此篇文章的由来。javascript
jQuery对跨域请求有两种解决方式各自是jQuery的jquery.ajax jsonp格式和jquery.getScript方式,而且这两种方式都仅仅支持get方法。前端
这里主要谈的是jsonp跨域的实现。java
json格式咱们却是常常使用,但是jsonp就不那么常常使用了,因此首先需要对jsonp要有一个了解。jquery
在解释JSONP以前,咱们需要了解下”同源策略“这个概念,这对理解跨域有帮助。基于安全的缘由,浏览器是存在同源策略机制的,同源策略阻止从一个源载入的文档或脚本获取或设置还有一个源载入额文档的属性。有点绕,说的简单点就是浏览器限制脚本仅仅能和同协议、同域名、同port的脚本进行交互。web
JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议。他赞成服务端生成script tags返回值client,经过javascript callback的形式来实现网站訪问。JSONP是一种script tag的注入,将server返回的response加入到页面是实现特定功能。ajax
简而言之,JSONP自己不是复杂的东西,就是经过scirpt标签对javascript文档的动态解析绕过了浏览器的同源策略。json
接下来,来实际模拟一个跨域请求的解决方式。后端为Spring MVC架构的,前端则经过Ajax进行跨域訪问。后端
一、首先client需要注冊一个callback(服务端经过该callback(jsonp)可以获得js函数名(jsonpCallback))。而后以JavaScript语跨域
法的方式,生成一个function浏览器
二、接下来,将JSON数据直接以入參的方式,放置到function中,这样就生成了一段js语法文档,返回给client。
三、最后client浏览器动态的解析script标签,并运行返回的JavaScript语法文档片断,此时数据做为參数传入到了预先定义好的
回调函数里(动态运行回调函数)。
这样的动态解析js文档和eval函数是相似的。
接下来就是怎样实现了,client代码。
$.ajax({ type: "get", async: false, url: "http://localhost:8080/buy/get", dataType: "jsonp", jsonp: "callbackparam", //服务端用于接收callback调用的function名的參数 jsonpCallback: "success_jsonpCallback", //callback的function名称,服务端会把名称和data一块儿传递回来 success: function(json) { alert(json[0].name); } });
注解:jsonp会建立一个查询字符串參数callback=?
,这个參数会载入请求的URL后面,服务端应当在JSON数据前加上回调函数
名,以便完毕一个JSONP请求。也就是说server端需要对返回的数据作处理,格式为例如如下形式:
jsonpCallback([{ name:"jhon"}])接下来看server端针对上述代码的处理:
@RequestMapping("/get") public void get(HttpServletRequest req,HttpServletResponse res) { res.setContentType("text/plain"); String callbackFunName =req.getParameter("callbackparam");//获得js函数名称 try { res.getWriter().write(callbackFunName + "([ { name:\"John\"}])"); //返回jsonp数据 } catch (IOException e) { e.printStackTrace(); } }
至此,Ajax跨域请求也已经攻克了,只是仍是有两点地方需要注意:
一、没有关于JSONP调用的错误处理,动态插入的脚本有效,则运行调用,无效就默默失败(无不论什么提示)。
二、JSONP被不信任的服务使用会有必定的安全隐患,不信任的服务提供的脚本多是恶意的。