cookie中的domain和path

Posted zh1164

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cookie中的domain和path相关的知识,希望对你有一定的参考价值。

1.cookie中的domain代表的是cookie所在的域,默认情况下就是请求的域名,例如请求http://www.server1.com/files/hello, 那么响应中的set-Cookie默认会使用www.server1.com作为cookie的domain,在浏览器中也是按照domain来组织cookie的。 我们可以在响应中设置cookie的domain为其他域,但是浏览器并不会去保存这些domain为其他域的cookie。

2.cookie中的path能够进一步的控制cookie的访问,当path=/; 当前域的所有请求都可以访问到这个cookie。 如果path设为其他值,比如path=/test,那么只有/test下面的请求可以访问到这个cookie。

纸上得来终觉浅,绝知此事要躬行。

首先我们来看看默认情况下的cookie的domain和path是什么。服务端使用servlet。

//这里故意将url设置的特别长,方便观察path的默认值
@WebServlet("/test/test1/test2.html")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie nameCookie = new Cookie("name", "zhangsan");
        response.addCookie(nameCookie);
        
        try(PrintWriter out = response.getWriter()){ out.print("set name cookie"); }
    }
}

 

上面的cookie没有任何特别设置,只有基本的名和值。响应的头信息中也是最基本的情况,如下图:

我们现在可以看看浏览器中保存了什么了。

我们从浏览器的保存情况中可以看出: 1. 浏览器是按照domain域来组织cookie的。

                  2. domain的默认值为请求的域名。

                  3. path的默认值为请求的上一层目录(请求为:/hello/test/test1/test2.html, path为/hello/test/test1)

 

更改cookie的domain和path值

我们可以改变cookie的domain和path的值,看看会发生什么。

@WebServlet("/test/test1/test2.html")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie nameCookie = new Cookie("name", "zhangsan");
        nameCookie.setDomain("www.example2.com");//domain 更改为其他的域名
        response.addCookie(nameCookie);

        Cookie ageCookie = new Cookie("age", "11");
        ageCookie.setPath("/"); //path 更改为根目录
        response.addCookie(ageCookie);
        
        try(PrintWriter out = response.getWriter()){ out.print("set name and age cookies"); }
    }
}

 

上面的代码中我们返回了两个cookie,nameCookie更改了domain,ageCookie更改了path,我们看看会发生些什么。

首先还是看看响应的头信息:

我们在代码中的改动完全反映到了响应的头信息中,但是浏览器的保存结果可能和你想象的不太一样。如下图:

我们看到浏览器仅仅保存了ageCookie,并没有保存nameCookie,实际上就是因为浏览器不会从一个响应中保存其他域名的cookie。

在网上看到一些关于更改domain的文章,包括使用js来实现的,但是我实践的结果都是不可以的。

 

path控制cookie的访问

我们不仅无法访问到其他域的cookie,我们同样无法访问到当前请求的url不在path属性之下的cookie。

@WebServlet("/test/test1/test2.html")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie nameCookie = new Cookie("name", "zhangsan");
        response.addCookie(nameCookie);

        Cookie ageCookie = new Cookie("age", "11");
        ageCookie.setPath("/"); //path 更改为根目录
        response.addCookie(ageCookie);
        
        try(PrintWriter out = response.getWriter()){ out.print("set name and age cookies"); }
    }
}

 

上面的代码中nameCookie使用默认path,也就是 /hello/test/test1, ageCookie使用根目录作为path。 我们从两个不同的路径来访问cookie,代码如下:

//@WebServlet("/test/test2/access.html")
@WebServlet("/test/test1/access.html")
public class AccessServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try(PrintWriter out = response.getWriter();){
            Cookie[] cs = request.getCookies();
            if(cs != null){
                for(Cookie c : cs){
                    out.print(c.getName() + " --> " + c.getValue());
                }
            }
        }
    }
}

 

分别从两个url来访问,结果/test/test2/access.html仅仅能访问到age,而/test/test1/access.html能够访问到age和name。 

 

注意:在Apache Http Server 反向代理中,如果我们不去更改cookie中domain和path的值,就有可能出现 浏览器根本不会去保存这个cookie或者即使保存了也无法正常访问的情况。

 

以上是关于cookie中的domain和path的主要内容,如果未能解决你的问题,请参考以下文章

Cookie中的domain与path属性详解

理解cookie的path和domain属性(转)

php setcookie中path和domain怎么设置

Tornado中的Cookie设置

javascript 操作cookie

如何封装一个Cookie库