几乎每一个前端童鞋在简历上多少都会提到ajax,json,jsonp这样的关键词,特别是有些同学并不知道jsonp到底是个什么鬼,写在简历上会不会为自己加分呢?
今天小寒同学就给大家聊聊jsonp吧,提到json和jsonp,大家都知道json是一种数据格式,在前后台交互使用比较广泛,jsonp是一种数据交换方式,适用于解决跨域问题。
首先我们明确定义,跨域,什么叫跨域,简单的说就是请求本站(本域名)之外的资源都属于跨域请求。实际上个人觉得跨域用的并不多,并没有那么多需要跨域请求的时候。当然我们更关注的是如何处理跨域问题,目前从网上可以看到很多的文章,大多都是通过script标签实现,实际上有src的标签都是可以跨越的,比如img,其次跨域需要服务端支持,也就是服务端允许客户端跨域访问。
接下来我们看一个实例:
本站有个功能是提供百度统计数据获取,目前百度统计可以对网站访问情况做一个很好的记录和分析,但却没有提供一个简单的数据输出方式,因此本站做了此接口;
接口实现的方式很简单,用户提供相关的百度统计账户信息及站点信息,本站通过百度接口查询并返回,其中支持jsonp方式调用,返回内容有两种HTML输出,jsonp返回,本文只针对jsonp返回做说明,首先我们看一下服务端代码:
/** * 获取统计包信息,含昨日,今日,历史总共;此方法输出该用户所有站点统计信息 * 返回json数据,服务端已设置允许跨域,如失败的话请采用jsonp方式请求,默认回调方法为callback * @return json * @author shy * @date 2016-11-16 下午03:20:33 */ @RequestMapping("/getCountPack/jsonp") public String getCountPack(String email,Integer siteId,String callback,HttpServletResponse response){ //服务端允许跨域 response.setHeader("Access-Control-Allow-Origin", "*"); Gson gson = new Gson(); if(StringUtils.isNotEmpty(email) && null != siteId){ UserInfo user = userService.getByEmail(email); if(null != user){ WebsiteUser site = new WebsiteUser(); site.setUser(user); site.setSiteId(siteId); site = websiteUserService.getWebsiteUserBySiteInfo(site); if(null != site){ CountPack pack = getSiteCountPack(site); if(StringUtils.isNotEmpty(callback)){ writeResponseAsync(new StringBuffer(callback + "(" +gson.toJson(pack) + ")"),response); }else{ writeResponseAsync(new StringBuffer("callback("+gson.toJson(pack)+")"),response); } } } } return ""; }
请求脚本如下
参数说明:
{
email:String本站注册邮箱,
siteId:Integer 在本站添加的站点siteId,
callback:回调方法,默认为"callback"
}
返回内容:
jsonpcallback({"today":{"pv":138,"uv":12,"ip":10,"nv":8},"yesterday":{"pv":392,"uv":24,"ip":28,"nv":15},"history":{"pv":3468,"uv":246,"ip":143,"nv":246}})
返回说明:如果将()中内容看作一个json对象,其实返回的就是一个javascript语句,调用jsoncallback方法,参数是json对象;当然调用之前首先要定义jsonpcallback方法了。
客户端代码:
//方法定义必须在调用之前//方法定义必须在调用之前
补充说明,jsonp请求可以通过script标签,也可以通过ajax jsonp方式请求,但个人推荐script,更简单整洁