你的浏览器不支持canvas

做你害怕做的事情,然后你会发现,不过如此。

不同域名之间通过JSONP跨域共享cookie

时间: 作者: 黄运鑫

本文章属原创文章,未经作者许可,禁止转载,复制,下载,以及用作商业用途。原作者保留所有解释权。


共享cookie有什么用

  • 共享cookie在SSO单点登录的应用,比如淘宝www.taobao.com和天猫www.tmall.com两个不同域名的网站,两个网站共用一个用户中心。在淘宝登录后再访问天猫,则直接是登录状态。实现逻辑就是通过JSONP请求来获取另一个域名下用户登陆后的cookie

不同域名通过JSONP共享cookie

  • 需要两个页面a.htmlb.html,还需要一个接口处理JSONP请求。
  • a.html代码如下,用来模拟用户登陆后将token保存到cookie
<html>
<head>
    <title>a.html</title>
    <meta charset="utf-8">
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<div>
    <input id="saveCookie" type="button" value="保存cookie"/>
    <br/>
    <textarea id="cookie" style="width: 400px;height: 50px;">testToken</textarea>
</div>
</body>
</html>
<script>
    $(function () {
        //保存cookie
        $("#saveCookie").on("click", function () {
            document.cookie = "token=" + $("#cookie").val() + ";path=/;";
        });
    });
</script>
  • b.html代码如下,用来发送JSONP请求,获取a.html中保存到cookietoken
<html>
<head>
    <title>b.html</title>
    <meta charset="utf-8">
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<div>
    <input id="jsonp" type="button" value="发送jsonp请求获取cookie"/>
</div>
</body>
</html>
<script>
    $(function () {
        //通过jsonp请求,获取localhost域名下的cookie
        //通过向localhost域名发起jsonp请求,会自动带上localhost域名下的所有cookie,这样后台就能获取到localhost的cookie,再通过
        /**
         * 向localhost域名发起jsonp请求,请求会自动带上localhost域名下的所有cookie
         * 这样后台就能获取到localhost的cookie,在接口返回的回调方法jsonpscall中,将指定的cookie保存到当前域名下
         */
        $("#jsonp").on("click", function () {
            $.ajax({
                type: "get",
                async: false,
                url: "http://localhost:8080/jsonp",
                dataType: "jsonp",
                jsonp: "callback",
                jsonpCallback: "jsonpscall",//自定义的jsonp回调函数名称,请求成功后会执行后台返回的jsonpscall方法
                success: function (jsons) {
                    console.log("成功");
                },
                error: function () {
                    console.log("失败");
                }
            });
        });

    });

    //保存cookie的方法
    function setCookie(name, value) {
        document.cookie = name + "=" + value + ";path=/;";
    }
</script>
  • 后台接口代码如下:
@RestController
public class JsonpController {

    /**
     * 通过request获取请求中携带的cookie
     * produces必须为application/javascript,不然会报错
     */
    @GetMapping(value = "/jsonp", produces = "application/javascript")
    public String jsonp(HttpServletRequest request) {
        String token = null;
        //获取cookie
        Cookie[] cookies = request.getCookies();
        for (int i = 0; i < cookies.length; i++) {
            //获取key为token的cookie
            if (cookies[i].getName().equals("token")) {
                token = cookies[i].getValue();
                break;
            }
        }
        //回调方法,此方法会调用b.html页面中的setCookie(name, value)方法,将token保存到b.html的域名下
        return "jsonpscall(setCookie(\"token\",\"" + token + "\",1))";
    }
}
  • 首先启动a.html页面,页面域名为localhost,此页面可以看作是多个应用共用的用户中心,用来验证登录并将登录信息保存到cookie
  • 点击保存token按钮,将token保存到cookie,保存的cookie域名为localhost,如下图:

image

  • 再在同一浏览器窗口中启动b.html页面,为了方便演示域名改为了127.0.0.1,此页面可以看作某个应用,通过获取localhost下的cookie来自动登录。
  • 点击发送jsonp请求按钮,向http://localhost:8080/jsonp接口发送请求,后台接口数据如下:

image

  • 请求成功后,会将接口获取到的a.html中的token保存到b.htmlcookie中,保存的cookie域名为127.0.0.1,如下图:

image

  • 这样b.html就可以使用127.0.0.1下的token直接和后台交互,不需要重新登录。

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。