前言:
在做项目的时候,遇到考虑到外网使用的情况。因为地址域的不同,导致到请求不成功。因此需要考虑使用跨域技术来解决。在权衡各种跨域技术后优先选择JSONP。
什么是JSONP:
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
js代码
var ajaxUrl = "http://192.168.8.141:9092/project/rest/team/matchResult/1/20/1/1000"; function localHandler(data) { console.log("fengshu") console.log(data); } var ajaxParam = { async: false, url: ajaxUrl, type: "GET", dataType: 'jsonp',//非正式跨域传输协议 jsonp: 'callback', jsonpCallback:'localHandler', success: function (json) { //回调数据在localHandler处理 } }; $.ajax(ajaxParam); |
java代码
@RequestMapping("/matchResult/{page}/{pageSize}/{type}/{matchId}") public void getMatchResult(HttpServletResponse response, @PathVariable("page") int page, @PathVariable("pageSize") int pageSize, @PathVariable("type") String type,@PathVariable("matchId") String matchId) { EntityList<MatchResult> datas = dddService.getTeamRanks(matchId,type,page,pageSize); ObjectMapper objectMapper = new ObjectMapper(); String jsonResult=null; try { jsonResult = objectMapper.writeValueAsString(datas); } catch (JsonGenerationException e1) { e1.printStackTrace(); } catch (JsonMappingException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } PrintWriter out=null; response.setCharacterEncoding("UTF-8"); try { out = response.getWriter(); } catch (IOException e) { e.printStackTrace(); } out.println( "localHandler("+jsonResult + ")"); out.close(); } |
回调函数
localHandler({code: 0, detail: "操作成功"},value:[{chineseName: "权限系统--线上开发", redirectUrl: "http://auth.test.com:8810/"}]) |
这里可以看到返回的是一个方法,里面包含JSON。FUNCTION(JSON)格式。FOUNCTION NAME是前端传给后端(jsonpCallback:'localHandler'),后端接受FOUNCTION NAME把JSON数据进行包装,返回给前端实现跨域。
这里还有另外一个用法 因为返回的方法,前端只要预先定义好一个方法,后端决定返回时间,后端可以决定何时实现方法。
JSONP关键字介绍:
dataType | 从服务器返回你期望的数据类型。 (xml, json, script, or html) |
---|---|
jsonp | 在一个JSONP请求中重写回调函数的名字。这个值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,比如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。 |
jsonpCallback | 为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成一个独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。 |
JSONP原理:
我们不能从不同的服务器ajax数据,但是<script>就可以做到,我们在本地写一个函数,然后在远端引入的这个js文件对这个函数进行了调用,在调用过程中可以传递参数,这样子的一个过程就是jsonp。
<script type="text/javascript"> var localFunction = function(data){ alert('我是外域remote.js"); }; </script> <script type="text/javascript" src="http://remoteserver.com/remote.js"></script> |
JSONP需要注意问题:
1.JSONP是get请求 传输产数有限,如果产数过多要改用CORS来处理。
2.安全问题,其他人可以通过注入代码到HTML DOM,进行一些外站访问,获取数据或注入外部代码。(这个可以做application/json-p安全子集来预防)