加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

学习淘淘商城第九十五课(jsonp的原理及两种实现方式)

发布时间:2020-12-16 18:46:51 所属栏目:百科 来源:网络整理
导读:首先,说下什么是跨域?有以下两种: 1.域名不同 2.域名相同,端口不同 接着说下什么是jsonp? jsonp不是新技术,它只是一种解决方案,使用js的特性绕过跨域请求,利用的特性便是js可以跨域加载js文件!!举个非常常见的例子,我们在html头部一般都会引入很

首先,说下什么是跨域?有以下两种:

1.域名不同

2.域名相同,端口不同

接着说下什么是jsonp?

jsonp不是新技术,它只是一种解决方案,使用js的特性绕过跨域请求,利用的特性便是js可以跨域加载js文件!!举个非常常见的例子,我们在html头部一般都会引入很多js,甚至我们直接引用在线的js,比如我们引用官方网站的jQuery路径加载进来也是可以的。JQuery的官方域名与我们的工程所在的域名肯定是不一样的,但是不影响使用,这就是我们所说的js可以跨域请求js文件!

跨域的特点是什么呢?我们可以在"Network"一栏看到请求的token信息,在Headers当中发现服务端已经正常响应了,如下图所示。


我们再看下Response一栏,发现没有任何信息,其实流程是这样的,我们使用ajax调用服务端的接口,服务端不管你请求是否是同一个域下,只管响应,于是 我们可以看到服务端响应的头信息,但是当数据经过浏览器时,浏览器判断出js访问的数据来自不同的域,于是便拒绝将数据返给页面。我们拿不到Response信息,也就无法展示内容了。


那么jsonp是怎样解决跨域问题的呢?流程图如下,图的上半部分展示的是传统跨域请求,这种请求我们是获取不到Response数据的,下半部分是介绍jsonp跨域获取数据的方案的。我们现在要跨域获取信息的js当中添加一个函数,该函数有返回值参数data,发起跨域请求的一端引入服务端定义好的一个js文件,请求的参数中是带callback回调函数的,并且callback=mycall中的"mycall"一定是与我们添加的那个函数的名称一致的,服务端接收到请求,就进行响应,并且判断参数中是否有callback参数,如果有callback参数的话,就对要返回的数据进行处理,加工成一段js代码(很简单,就是把一个json串包装成一个js函数,如下图mycall({id:1,name:z});)然后响应,js本来就是要请求访问服务端的一个js文件,现在返回的也是js代码,于是浏览器将不再进行拦截,由于返回的是js代码,而且js语句有个特点就是,一旦响应到浏览器端便立即执行,我们已经添加了该函数,于是便调用我们添加的那个函数,我们只需把数据做下处理并进行展示就可以了!!!


下面我们便来实现jsonp请求,上图所介绍的方法是比较复杂的,如果我们用jquery的话,如下图所示。


这样就会帮我们省很多事,我们只需要在ajax请求时指定dataType为jsonp,如下图所示。jquery便会帮我们自动创建一个函数。


我们刷新下淘淘商城首页,可以看到请求中自动为我们加上了回调函数,而且随机为我们添加了函数名为"jQuery3257776"的函数。


现在我们要做的便是修改服务端的代码,以便能够配合客户端完成整个请求过程,修改的方法如下图所示,我们将原来返回一个Map类型改为返回String类型,而且添加了callback参数,判断下是否有callback参数,如果有就说明是jsonp请求,我们要将result转换成json串并且包装成一个js函数返回。如果不是jsonp请求,那就直接将result转换成json串返回。


修改后代码如下:

@RequestMapping(value = "/user/token/{token}",method = RequestMethod.GET)  
    @ResponseBody  
    public String getUserByToken(@PathVariable String token,String callback){  
        TaotaoResult result = userService.getUserByToken(token);  
        if(StringUtils.isNotBlank(callback)){
        	return callback+"("+JSON.toJSONString(result)+");";
        }
        return JSON.toJSONString(result);  
    } 
好了,代码修改完了,我们现在重启taotao-sso-web工程,重启后,我们刷新淘淘商城首页,发现页面正常显示用户的姓名了!! 注意,如果你这时还显示不出来,是因为token已经过期了,你需要重新登录一下,这样就可以看到了。


上面介绍的是最通用的一种方法,还有一种方法也可以解决,只是要求Spring的版本是4.1以上,还好,我们的淘淘商城用的版本是4.2,因此是没问题的,要修改的还是UserController,如下图所示。


修改后代码如下,由于result和mappingJacksonValue 属于不同类型,因此返回值类型修改成了Object。

@RequestMapping(value = "/user/token/{token}",method = RequestMethod.GET)  
    @ResponseBody  
    public Object getUserByToken(@PathVariable String token,String callback){  
        TaotaoResult result = userService.getUserByToken(token);  
        if(StringUtils.isNotBlank(callback)){
        	MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
        	mappingJacksonValue.setJsonpFunction(callback);
        	return mappingJacksonValue;
        }
        return result;  
    }
我们重启下taotao-sso-web工程,然后重新刷新下淘淘商城首页,如下图所示,发现也可以正常显示用户名!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读