zoukankan      html  css  js  c++  java
  • day78_淘淘商城项目_11_单点登录系统实现 + 用户名回显 + ajax请求跨域问题详解_匠心笔记

    课程计划

    • 1、SSO注册功能实现
    • 2、SSO登录功能实现
    • 3、通过token获得用户信息
    • 4、ajax跨域请求解决方案--jsonp

    1、服务接口实现

      SSO系统就是解决分布式环境下登录问题的,本质上是解决分布式环境下session共享问题。

    1.1、检查数据是否可用接口开发

    检查数据是否可用作为注册功能的辅助。

    1.1.1、功能分析

    请求的url:/user/check/{param}/{type}
    参数:从url中取参数
      1、String param(要校验的数据)
      2、Integer type(校验的数据类型)
    响应的数据:json数据。TaotaoResult,封装的数据校验的结果为true:表示成功,数据可用,false:失败,数据不可用。
    业务逻辑:
      1、从tb_user表中查询数据。
      2、查询条件根据传递过来的参数动态生成。
      3、判断查询结果,如果查询到数据就返回false。
      4、如果没有查询到数据就返回true。
      5、使用TaotaoResult包装,并返回。

    1.1.2、Dao

      从tb_user表查询。属于单表查询,可以使用逆向工程生成的代码。

    1.1.3、Service

    先在taotao-sso-interface中定义接口UserRegisterService,
    再在taotao-sso-service中写实现类。
    参数:
      1、要校验的数据:String param
      2、数据类型:Integer type(1、2、3分别代表username、phone、email)
    返回值:TaotaoResult
    在taotao-sso-interface创建接口

    /**
     * 用户注册管理接口
     * @author chenmingjun
     * @date 2018年12月3日 上午9:47:29
     * @version V1.0
     */

    public interface UserRegisterService {
        /**
         * 检查APP传过来的数据是否可用
         * @param param 要校验的数据
         * @param type 校验的数据类型
         * @return
         */

        TaotaoResult checkData(String param, Integer type);
    }

    在taotao-sso-service创建实现类

        @Autowired
        private TbUserMapper tbUserMapper;

        @Override
        public TaotaoResult checkData(String param, Integer type) {
            // 1、从tb_user表中查询数据
            TbUserExample example = new TbUserExample();
            Criteria criteria = example.createCriteria();
            // 2、查询条件根据传递过来的参数动态生成
            // 1、2、3分别代表username、phone、email
            if (type == 1) {
                criteria.andUsernameEqualTo(param);
            } else if (type == 2) {
                criteria.andPhoneEqualTo(param);
            } else if (type == 3) {
                criteria.andEmailEqualTo(param);
            } else {
                return TaotaoResult.build(400"传递过来的是非法的参数");
            }
            // 执行查询
            List<TbUser> list = tbUserMapper.selectByExample(example);
            // 3、判断查询结果,如果查询到数据就返回false
            if (list == null || list.size() == 0) {
                // 4、如果没有查询到数据就返回true
                return TaotaoResult.ok(true);
            }
            // 5、使用TaotaoResult包装,并返回
            return TaotaoResult.ok(false);
        }

    1.1.4、发布服务

    先在taotao-sso-service工程中的pom.xml文件中配置对taotao-sso-interface的依赖,因为服务层发布服务要通过该接口,
    再在taotao-sso-service工程中的applicationContext-service.xml文件中发布服务:

    1.1.5、引用服务

    需要在taotao-sso-web中实现。
    先在taotao-sso-web工程中的pom.xml文件中配置对taotao-sso-interface的依赖,表现层调用服务要通过该接口,
    在taotao-sso-web工程中的springmvc.xml文件中引用服务:

    1.1.6、Controller

    请求的url:/user/check/{param}/{type}
    参数:从url中取参数
      1、String param(要校验的数据)
      2、Integer type(校验的数据类型)
    请求的方法:get。
    响应的数据:json数据。TaotaoResult,封装的数据校验的结果,true:成功;false:失败。

    /**
     * 用户处理Controller
     * @author chenmingjun
     * @date 2018年12月3日 上午10:31:38
     * @version V1.0
     */

    @Controller
    public class UserController {

        @Autowired
        private UserRegisterService userRegisterService;

        @RequestMapping(value="/user/check/{param}/{type}", method=RequestMethod.GET)
        @ResponseBody
        public TaotaoResult checkData(@PathVariable String param, @PathVariable Integer type) {
            TaotaoResult result = userRegisterService.checkData(param, type);
            return result;
        }
    }

    1.1.7、测试

    get请求好测试,直接在浏览器中输入URL即可。
    访问地址:http://localhost:8088/user/check/zhangsan/1
    浏览器报404错误,原因是:我们web.xml中配置的是拦截以“.html”为后缀的请求。
    我们修改访问地址:http://localhost:8088/user/check/zhangsan/1.html
    此时浏览器报406错误。原因如下图:


    而且如果我们在请求后面加上“.html”的话,等于我们修改了接口开发文档,这是不行的。
    正确的做法是要拦截不带后缀的请求,我们使用“/”即拦截所有请求,如下图所示:

    下面我们详解406错误的形成原因?
    答:当我们浏览器出现406错误时,90%的原因是因为没有导入jackson-core-2.4.2.jar这个包。10%的原因是我们请求的URL后缀是“.html”。为什么呢?
    原因是:在springMVC中使用注解@ResponseBody,springMVC认为对于后缀是“.html”的URL请求,服务端返回的应该也是一个html页面。但是如果服务端返回的是一个java对象的话,那么浏览器不能将一个java对象转换成一个html对象,即就会报406错误。(这是一个大坑!

    1.2、用户注册接口开发

    1.2.1、功能分析


    请求的url:/user/register
    参数:表单的数据:username、password、phone、email
    返回值:json数据。TaotaoResult。
    接收参数:使用TbUser对象接收。
    请求的方法:post
    业务逻辑:
      1、使用TbUser接收提交的请求。
      2、补全TbUser其他属性。
      3、密码要进行MD5加密
      4、把用户信息插入到数据库中。
      5、返回TaotaoResult.ok()。

    1.2.2、Dao

      可以使用逆向工程生成的代码。

    1.2.3、Service

    在taotao-sso-interface中定义接口UserRegisterService已经定义好了,我们直接添加方法即可。
    再在taotao-sso-service中写实现类,我们已经定义好了,直接实现方法即可。
    参数:TbUser
    返回值:TaotaoResult
    在taotao-sso-interface创建接口

        /**
         * 用户注册
         * @param tbUser 用户表
         * @return
         */

        TaotaoResult register(TbUser tbUser);
    }

    在taotao-sso-service创建实现类

        @Override
        public TaotaoResult register(TbUser tbUser) {
            // 1、校验用户名和密码不能为空
            if (StringUtils.isEmpty(tbUser.getUsername())) {
                return TaotaoResult.build(400"注册失败,用户名不能为空");
            }
            if (StringUtils.isEmpty(tbUser.getPassword())) {
                return TaotaoResult.build(400"注册失败,密码不能为空");
            }
            // 2、校验数据的可用性
            // 2.1 、校验username是否可用
            TaotaoResult checkData = checkData(tbUser.getUsername(), 1);

            if (!(boolean) checkData.getData()) { // 说明username不可用,返回400
                return TaotaoResult.build(400"用户名已被使用");
            }
            // 2.2、校验phone是否可用
            if (StringUtils.isNotBlank(tbUser.getPhone())) { // 说明phone不为空
                if (!(boolean) checkData.getData()) { // 说明phone不可用,返回400
                    return TaotaoResult.build(400"手机号已被使用");
                }
            }
            // 2.3、校验email是否可用
            if (StringUtils.isNotBlank(tbUser.getEmail())) { // 说明email不为空
                if (!(boolean) checkData.getData()) { // 说明email不可用,返回400
                    return TaotaoResult.build(400"邮箱已被使用");
                }
            }

            // 补全TbUser其他属性
            tbUser.setCreated(new Date());
            tbUser.setUpdated(tbUser.getCreated());
            // 密码的MD5加密处理
            String password = tbUser.getPassword();
            String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
            tbUser.setPassword(md5Password);

            // 把用户信息插入到数据库中
            tbUserMapper.insertSelective(tbUser);
            return TaotaoResult.ok();
        }

    1.2.4、发布服务

      在taotao-sso-service工程中applicationContext-service.xml文件中发布服务,上面“1.1.4”中已经发布过了。不在赘图!

    1.2.5、引用服务

      在taotao-sso-web工程中的springmvc.xml文件中引用服务,上面“1.1.5”中已经引用过了。不在赘图!

    1.2.6、Controller

    请求的url:/user/register
    参数:表单的数据:username、password、phone、email
    返回值:json数据。TaotaoResult。
    接收参数:使用TbUser对象接收。
    请求的方法:post

        @RequestMapping(value="/user/register", method=RequestMethod.POST)
        @ResponseBody
        public TaotaoResult register(TbUser tbUser) {
            TaotaoResult result = userRegisterService.register(tbUser);
            return result;
        }

    1.2.7、测试

    post请求不好测试,需要我们新建表单,太麻烦了,我们可以使用一个工具。如下:


    可以使用restclient-ui-3.5-jar-with-dependencies.jar测试接口。
    点击编辑按钮,填写表单提交的content-type:application/x-www-form-urlencoded

    点击插入参数按钮,填写参数后,点击生成。

    点击提交按钮,测试开始。

    1.3、用户登录接口开发

    1.3.1、功能分析


    请求的url:/user/login
    请求的方法:POST
    参数:username、password,表单提交的数据。可以使用方法的形参接收。
    返回值:json数据,使用TaotaoResult包含一个token。
    业务逻辑:
    登录的业务流程:

    登录的处理流程:
      1、登录页面提交用户名密码。
      2、登录成功后生成token。token相当于原来的jsessionid,字符串,可以使用uuid。
      3、把用户信息保存到redis。key就是token,value就是TbUser对象转换成的json字符串。
      4、使用String类型保存session信息。可以使用“前缀:token”为key。
      5、设置key的过期时间。模拟session的过期时间。一般半个小时。
      6、把token写入cookie中。
      7、cookie需要跨域。例如:www.taotao.comsso.taotao.comorder.taotao.com,可以使用工具类。
      8、cookie的有效期。关闭浏览器失效。
      9、登录成功。

    1.3.2、Dao

      查询tb_user表。单表查询。可以使用逆向工程生成的代码。

    1.3.3、Service

    参数:
      1、用户名:String username
      2、密码:String password
    返回值:TaotaoResult,包装token。
    业务逻辑:
      1、判断用户名和密码是否正确。
      2、登录成功后生成token。token相当于原来的jsessionid,字符串,可以使用uuid。
      3、把用户信息保存到redis。key就是token,value就是TbUser对象转换成的json串。
      4、使用String类型保存session信息。可以使用“前缀:token”为key。
      5、设置key的过期时间。模拟session的过期时间。一般半个小时。
      6、返回TaotaoResult包装token。
    部分代码:需要设置加载属性文件。
    在taotao-sso-interface创建接口

    /**
     * 用户登录管理接口
     * @author chenmingjun
     * @date 2018年12月3日 下午6:04:21
     * @version V1.0
     */

    public interface UserLoginService {

        /**
         * 根据用户名和密码进行登录,生成token作为key,user作为value
         * @param username
         * @param password
         * @return
         */

        TaotaoResult login(String username, String password);
    }

    在taotao-sso-service创建实现类

    @Service
    public class UserLoginServiceImpl implements UserLoginService {

        @Autowired
        private TbUserMapper tbUserMapper;

        // 注入jedisClient对象
        @Autowired
        private JedisClient jedisClient;

        @Value("${USER_SESSION}")
        private String USER_SESSION;

        @Value("${SESSION_EXPIRE}")
        private Integer SESSION_EXPIRE;

        @Override
        public TaotaoResult login(String username, String password) {
            // 1、判断用户名和密码是否正确。
            TbUserExample example = new TbUserExample();
            Criteria criteria = example.createCriteria();
            criteria.andUsernameEqualTo(username);
            // 查询用户信息,校验用户名
            List<TbUser> list = tbUserMapper.selectByExample(example);
            if (list == null || list.size() == 0) { // 说明没有查询到用户信息,即用户名输入错误
                return TaotaoResult.build(400"用户名或密码错误");
            }
            // 取出用户信息,校验密码
            TbUser tbUser = list.get(0);
            if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(tbUser.getPassword())) { // 说明密码不正确
                return TaotaoResult.build(400"用户名或密码错误");
            }

            // 2、登录成功后生成token。token相当于原来的jsessionid,字符串,可以使用uuid。
            String token = UUID.randomUUID().toString();
            // 我们密码就不要存到redis中了,所以要清空密码
            tbUser.setPassword(null);
            // 3、把用户信息保存到redis。key就是token,value就是TbUser对象转换成的json串。
            // 4、使用String类型保存session信息。可以使用“前缀:token”为key。
            jedisClient.set(USER_SESSION + ":" + token, JsonUtils.objectToJson(tbUser));
            // 5、设置key的过期时间。模拟session的过期时间。一般半个小时。
            jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);

            // 6、返回TaotaoResult包装token。
            return TaotaoResult.ok(token);
        }
    }

    1.3.4、发布服务

    在taotao-sso-service工程中applicationContext-service.xml文件中发布服务:


    在taotao-sso-service工程中applicationContext-dao.xml文件中加载配置文件:

    配置文件内容如下:

    1.3.5、引用服务

    在taotao-sso-web工程中的springmvc.xml文件中引用服务:

    1.3.6、Controller

    请求的url:/user/login
    请求的方法:POST
    参数:username、password,表单提交的数据。
    因为只有两个参数,所以不用使用pojo来接收,可以使用方法的形参接收就可以。
    从返回结果中取出token,写入cookie。需要使用HttpServletRequest、HttpServletResponse
    返回值:json数据,使用TaotaoResult包含一个token。
    业务逻辑:
      1、接收表单提交的两个参数。
      2、调用Service层的方法进行登录。
      3、从返回结果中取token,写入cookie。注意:cookie要跨域。
       cookie的二级域名跨域需要进行设置
       1)setDomain(),设置一级域名:
        .itcast.cn
        .taotao.com
        .taotao.com.cn
       2)setPath(),设置为“/”
       可以使用工具类。工具类放到taotao-common工程中。


       需要加入servlet-api的依赖包:在common项目中的pom.xml中,加入依赖:
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>

    注意:scope的值是provided,表示该jar包在运行时使用编译时使用测试时用,但是打包的时候不用,因为该jar包web容器tomcat会提供,如果打包的时候使用该jar包,会出现冲突
      4、响应数据。json数据。TaotaoResult,其中包含token。

        @RequestMapping(value="/user/login", method=RequestMethod.POST)
        @ResponseBody
        public TaotaoResult login(String username, String password, HttpServletRequest request, HttpServletResponse response) {
            // 1、接收表单提交的两个参数。
            // 2、调用Service层的方法进行登录。
            TaotaoResult result = userLoginService.login(username, password);
            // 3、从返回结果中取出token,写入cookie。注意:cookie要跨域。
            if (result.getStatus() == 200) {
                String token = result.getData().toString(); // 从返回结果中取出token
                CookieUtils.setCookie(request, response, COOKIE_TOKEN_KEY, token);
            }
            return result;
        }

    在taotao-sso-web工程中springmvc.xml文件中加载配置文件:


    配置文件内容如下:

    1.3.7、测试

    使用restclient-ui-3.5-jar-with-dependencies.jar测试接口,查看Body;然后查看redis服务器中的key。

    1.4、通过token查询用户信息接口开发

    1.4.1、功能分析


    请求的url:/user/token/{token}
    参数:String token(需要从url中取)
    返回值:json数据。使用TaotaoResult包装Tbuser对象。
    业务逻辑:
      1、从url中取参数。
      2、根据token查询redis。
      3、如果查询不到数据,则返回用户已经过期。
      4、如果查询到数据,则说明用户已经登录。
      5、需要重置key的过期时间。
      6、把json数据转换成TbUser对象,然后使用TaotaoResult包装并返回。

    1.4.2、Dao

      使用JedisClient对象进行查询。

    1.4.3、Service

    参数:String token
    返回值:TaotaoResult
    在taotao-sso-interface创建接口

        /**
         * 根据token从redis中查询用户信息
         * @param token
         * @return
         */

        TaotaoResult getUserByToken(String token);

    在taotao-sso-service创建实现类

        @Override
        public TaotaoResult getUserByToken(String token) {
            // 2、根据token查询redis。
            String jsonString = jedisClient.get(USER_SESSION + ":" + token);
            if (StringUtils.isBlank(jsonString)) {
                // 3、如果查询不到数据,则返回用户已经过期。
                return TaotaoResult.build(400"用户登录状态已过期,请重新登录");
            }
            // 4、如果查询到数据,则说明用户已经登录。
            // 5、需要重置key(USER_SESSION)的过期时间。
            jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
            // 6、把json数据转换成TbUser对象,然后使用TaotaoResult包装并返回。
            TbUser tbUser = JsonUtils.jsonToPojo(jsonString, TbUser.class);
            return TaotaoResult.ok(tbUser);
            // return TaotaoResult.ok(json);
        }

    注意:如果返回的是:return TaotaoResult.ok(json);
    那么返回的json串中会有转义字符,如下:

    {
    "status"200
    "msg""OK"
    "data""{"id":1,"username":"zhangsan","password":null,"phone":"15800807944","email":"420840806@qq.com","created":1414119176000,"updated":1414119179000}"
    }

    这跟我们接口开发文档中的格式不一样,接口开发文档中的格式如下:

    {
    "status"200
    "msg""OK"
    "data": {"id":1,"username":"zhangzhijun","password":null,"phone":"15800807944","email":"420840806@qq.com","created":1414119176000,"updated":1414119179000}
    }

    1.4.4、发布服务

      在taotao-sso-service工程中applicationContext-service.xml文件中发布服务,上面“1.3.4”中已经发布过了。不在赘图!

    1.4.5、引用服务

      在taotao-sso-web工程中的springmvc.xml文件中引用服务,上面“1.3.5”中已经引用过了。不在赘图!

    1.4.6、Controller

    请求的url:/user/token/{token}
    参数:String token (需要从url中取)
    返回值:json数据。使用TaotaoResult包装Tbuser对象。

        @RequestMapping(value="/user/token/{token}", method=RequestMethod.GET)
        @ResponseBody
        public TaotaoResult getUserByToken(@PathVariable String token) {
            TaotaoResult result = userLoginService.getUserByToken(token);
            return result;
        }

    1.4.7、测试

    get请求好测试,直接在浏览器中输入URL即可。
    访问地址:http://localhost:8088/user/token/cd3c4925-c780-4e15-b8c2-ca9dc764fe47

    1.5、安全退出接口开发

    1.5.1、功能分析


    需要根据token删除redis中对应的key。
    从接口文档可知
    url:user/logout/{token}
    参数:token
    返回值:由TaotaoResule封装的信息"ok"。

    1.5.2、Dao

      直接使用RedisClient访问redis。

    1.5.3、Service

    在taotao-sso-interface创建接口

        /**
         * 根据token从redis删除对应的key
         * @param token
         * @return
         */

        TaotaoResult logout(String token);

    在taotao-sso-service创建实现类

        @Override
        public TaotaoResult logout(String token) {
            jedisClient.expire(USER_SESSION + ":" + token, 0);
            return TaotaoResult.ok();
        }

    1.5.4、发布服务

      在taotao-sso-service工程中applicationContext-service.xml文件中发布服务,上面“1.3.4”中已经发布过了。不在赘图!

    1.5.5、引用服务

      在taotao-sso-web工程中的springmvc.xml文件中引用服务,上面“1.3.5”中已经引用过了。不在赘图!

    1.5.6、Controller

    url:user/logout/{token}
    参数:token

        @RequestMapping(value="/user/logout/{token}", method=RequestMethod.GET)
        @ResponseBody
        public TaotaoResult logout(@PathVariable String token) {
            TaotaoResult result = userLoginService.logout(token);
            return result;
        }

    1.5.7、测试

    安装taotao-sso,启动taotao-sso、taotao-sso-web。
    从redis中找一个存在的token:70ae13a6-87bb-4e3a-b713-35d7979c4bd8
    使用RESETClirnt测试访问,删除token:70ae13a6-87bb-4e3a-b713-35d7979c4bd8 的用户
    提示删除成功!

    2、实现SSO系统的登录注册功能

    2.1、展示登录及注册页面及首页超链接修改

    第一步:加入静态文件及JSP页面


    第二步:在taotao-sso-web的springmvc.xml文件中配置资源映射标签,即不拦截静态资源。

    第三步:点击门户首页登录按钮,浏览器URL为:
      http://localhost:8084/page/login,报错:

    第四步:点击门户首页的免费注册按钮,浏览器的URL为:
      http://localhost:8084/page/register,报错:

    由此我们发现,其实登录注册的URL非常类似:
      http://localhost:8084/page/register
      http://localhost:8084/page/login
    所以通过/page/{page}的方式请求,通过URL模板映射,使用@PathVariable注解即可接收请求,转发jsp页面,代码如下:
    使用rsetful,跳转不同页面

    第五步:修改端口号为访问登录注册的端口号为8088

    测试:通过。

    2.2、注册功能实现

    /taotao-sso-web/src/main/webapp/WEB-INF/jsp/register.jsp分析:


    提交之前检查:

    注册,提交表单:

    分析得出,此时的登录功能应该是可以使用了。

    2.3、登录功能实现

    /taotao-sso-web/src/main/webapp/WEB-INF/jsp/login.jsp分析:


    文档加载时,调用方法,一旦点击,则提交表单:

    表单提交:

    分析得出,登录功能也是可以使用的。

    3、门户首页展示用户名

    3.1、首页展示用户名分析

    1、在taotao-sso-web工程中,当用户登录成功后,在cookie中有token信息。
    2、在taotao-portal-web工程中,从cookie中取出token,携带token发送格式为jsonp的请求,根据token从taotao-sso-web工程中查询用户信息。
    3、把从taotao-sso-web工程中查询到的用户名展示到首页taotao-portal-web工程中。
    方案一:在Controller中取cookie中的token数据,调用sso服务查询用户信息。
      缺点:由于淘淘商城首页footer.jsp,在每个系统中都有,可以在每一个系统的footer.jsp中写一个ajax发起请求调用当前系统的Controller,设置模型数据,然后展示数据。麻烦!
    方案二:当页面加载完成后使用js取cookie中token的数据,使用ajax请求查询用户信息的JSON数据。只需要在页面实现一次即可。
    乍一看方案一与方案二是一样的,其实不是,方案一需要在每一个系统都编写Controller,方案二只需要在taotao-sso-web编写一个Controller即可。而且方案一是立即可行的,但是方案二的服务接口在sso系统中。sso.taotao.com(localhost:8088),在首页显示用户名称,首页的域名是www.taotao.com(localhost:8082),使用ajax请求跨域了。
    什么是跨域:
      1、域名不同。
      2、域名相同端口不同。

    例如:
        www.taotao.com --> 请求 www.taobao.com  也是跨域
        www.taotao.com --> 请求 sso.taotao.com  也是跨域
        www.taotao.com:8080 --www.taotao.com:8088  也是跨域
        localhost:8080 --localhost:8088  也是跨域
        www.taotao.com --www.taotao.com  不是跨域

    只有域名和端口完全一样才不是跨域。
    js不可以跨域请求JSON数据
    解决js的跨域问题可以使用jsonp。
    jsonp不是新技术是跨域的解决方案。使用js的特性绕过跨域请求,特性:js可以跨域加载js文件

    3.2、jsonp原理

    举个非常常见的例子,我们在html头部一般都会引入很多js,甚至我们直接引用在线的js,比如我们引用官方网站的jQuery路径加载进来也是可以的。jQuery的官方域名与我们的工程所在的域名肯定是不一样的,但是不影响使用,这就是我们所说的js可以跨域请求js文件!
    即:ajax无法跨域请求别的url,我们可以使用ajax跨域加载js文件。


    http://localhost:8088/user/token/4ffd07a2-1f92-4601-94ff-2ab763931018?callback=fun
    8088做处理:查询到JSON数据,拼接成fun({"id":1});
    8082浏览器加载fun({"id":1});
    调用fun方法,里面参数就是JSON数据。做相关的处理。
    更加详细的解释:
    参考链接:https://blog.csdn.net/pdsu161530247/article/details/82189866

    3.3、jsonp实现

    3.3.1、客户端:使用ajax自带的callback函数

    使用jQuery。
    在/taotao-portal-web/src/main/webapp/js/taotao.js中:
    使用ajax的dataType : "jsonp",将success : function当做回调函数。
    客户端是taotao-portal-web工程:


    taotao.js代码如下:

    3.3.2、服务端:springmvc支持jsonp的两种实现方法

    ajax设置的callback函数,我们在后端就需要封装一个callback(jsondata),让前端将jsondata作为参数调用。
    方法一:springmvc4.1之前的实现方法
    服务端是taotao-sso-web工程:


    方法二:springmvc4.1之后的实现方法
    springmvc4.1以后,下面两行代码会自动帮我们封装callback(jsondata)
    服务端是taotao-sso-web工程:
  • 相关阅读:
    Qt计算器开发(三):执行效果及项目总结
    [HNOI2019]校园旅行
    How to fix nuget Unrecognized license type MIT when pack
    How to fix nuget Unrecognized license type MIT when pack
    git 通过 SublimeMerge 处理冲突
    git 通过 SublimeMerge 处理冲突
    git 上传当前分支
    git 上传当前分支
    gif 格式
    gif 格式
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/10066058.html
Copyright © 2011-2022 走看看