何时使用Request.Cookies而不是Response.Cookies?

61

在页面事件(例如加载)时,我是否使用“response”,因为这是来自ASP.NET的响应,而在按按钮时使用“request”,因为这是要发送给ASP.NET进行处理的响应?还是有更多需要注意的地方?

6个回答

102

它们是两个不同的东西,一个保存[响应],另一个读取[请求]。

在Cookie中(从信息学角度来看),你可以保存一个包含字符串对象的小文件一段时间

在.NET框架中,你可以使用以下方法保存cookie

HttpCookie myCookie = new HttpCookie("MyTestCookie");
DateTime now = DateTime.Now;

// Set the cookie value.
myCookie.Value = now.ToString();
// Set the cookie expiration date.
myCookie.Expires = now.AddMinutes(1);

// Add the cookie.
Response.Cookies.Add(myCookie);

Response.Write("<p> The cookie has been written.");

你写了一个cookie,它将在一分钟内可用...通常我们会使用now.AddMonth(1)来保存一个持续一个月的cookie。

要检索一个cookie,你可以使用请求(Request),例如:

Retrieve a cookie

HttpCookie myCookie = Request.Cookies["MyTestCookie"];

// Read the cookie information and display it.
if (myCookie != null)
   Response.Write("<p>"+ myCookie.Name + "<p>"+ myCookie.Value);
else
   Response.Write("not found");

记住:

要删除一个 Cookie,没有直接的代码,诀窍在于使用已经过期的时间来保存相同名称的 Cookie,例如now.AddMinutes(-1),这将会删除该 Cookie。

正如您所看到的,每当 Cookie 的生命周期到期时,该文件就会被系统自动删除。


7
+1 我没有意识到你需要重新保存 cookie 才能更新过期时间。 - Andrew
1
这个内容大部分是有帮助的,但有一点误导性,因为在你的例子中,当你尝试检索cookie时,实际上你用这行代码 HttpCookie myCookie = new HttpCookie("MyTestCookie"); 覆盖了之前保存的cookie。相反,应该使用类似这样的代码 HttpCookie myCookie = new HttpCookie("MyWrittenCookie"); - Off The Gold
2
这不支持读取刚刚在响应中发送的 cookie,此时您需要使用 Response.Cookies - ajbeaven
我相信这在编写服务器端代码时是正确的。对于客户端代码来说则恰好相反。 - AaA
为什么 Request.Cookies[""].Value 与我在浏览器中看到的值以及实际存储的值不同?我使用浏览器控制台检查了 cookie 的值。 - Mehdi Dehghani
@MehdiDehghani 从浏览器中,你只能访问浏览器的 cookies,而无法访问 Https 或服务器的 cookies。例如,确保你正在读取正确的 cookie,这里有一些技巧,同时也要确保服务器没有用其他值覆盖了该值... - balexandre

41

在Web应用程序中,请求是来自浏览器的内容,响应是服务器返回的内容。当验证来自浏览器的Cookie或Cookie数据时,应使用Request.Cookies。当您构建要发送到浏览器的Cookie时,需要将它们添加到Response.Cookies中。


澄清一下,在这里“服务器”指的是处理并响应浏览器请求的应用程序。 - Suncat2000

19

当编写Cookie时,请使用Response,但读取可能取决于您的情况。通常,您从Request中读取,但如果您的应用程序尝试获取刚编写或更新的Cookie,并且还没有回传到浏览器,则可能需要从Response中读取。

我已经使用这种模式一段时间了,对我来说效果很好。

public void WriteCookie(string name, string value)
{
    var cookie = new HttpCookie(name, value);
    HttpContext.Current.Response.Cookies.Set(cookie);
}


public string ReadCookie(string name)
{
    if (HttpContext.Current.Response.Cookies.AllKeys.Contains(name))
    {
        var cookie = HttpContext.Current.Response.Cookies[name];
        return cookie.Value;
    }

    if (HttpContext.Current.Request.Cookies.AllKeys.Contains(name))
    {
        var cookie = HttpContext.Current.Request.Cookies[name];
        return cookie.Value;
    }

    return null;
}

4
另一种同样有效的方法是在保存时将Cookie写入Response.Cookies和Request.Cookies集合中。这样,循环中的任何进一步逻辑都可以读取你刚设置的Cookie,而无需查看Response对象。 - Chris
1
Chris,同意,我以前也这样做,但最近读到修改请求对象是不可取的。会尝试找到参考资料。 - andleer
谢谢,Chris。Andrew--我很想看一下那个参考资料。现在我会采用Chris的解决方案。 - catfood

4

Cookie来自于Request.Cookies集合中的浏览器。您需要在那里读取发送的cookie。

要将cookie发送回浏览器,您需要将它们放入Response.Cookies集合中。

如果您想要删除一个cookie,您必须告诉浏览器通过发送一个已过期的cookie来删除它。浏览器使用客户端计算机的本地时间,因此如果您使用服务器时间创建日期,请确保至少减去一天以确保它实际上已经在客户端的本地时间中过期。


3

当我在.NET中创建或更新cookie时,通常会同时对请求和响应cookie集合进行操作。这样,如果您尝试在页面请求序列的后面读取cookie,您可以确信它将具有正确的信息。


Alex,这个问题一整天都困扰着我。感谢你简单明了地解决了它! - catfood
是的,有一些有趣的行为,如果在响应中设置Cookie,它也会在请求中设置,如果它之前不存在。但是,如果它已经存在于请求中,设置响应不会更新请求。因此,这似乎是一个旨在提供帮助但有些不一致的功能。当在同一请求中多次修改Cookie时,肯定会遇到错误。 - AaronLS

1

Andrew的代码在"AllKeys.Contains"方法中出现了错误。所以我进行了一些修正。

public void WriteCookie(string strCookieName, string strCookieValue)
    {
        var hcCookie = new HttpCookie(strCookieName, strCookieValue);
        HttpContext.Current.Response.Cookies.Set(hcCookie);
    }


    public string ReadCookie(string strCookieName)
    {    
        foreach (string strCookie in HttpContext.Current.Response.Cookies.AllKeys)
        {
            if (strCookie == strCookieName)
            {
                return HttpContext.Current.Response.Cookies[strCookie].Value;
            }
        }         

        foreach (string strCookie in HttpContext.Current.Request.Cookies.AllKeys)
        {
            if (strCookie == strCookieName)
            {
                return HttpContext.Current.Request.Cookies[strCookie].Value;
            }
        }

        return null;
    }

1
你记得包含 System.Linq 吗?这样做可以纠正我的文件中的错误。 - chocojosh
2
如果只是一个小错误,最好在复制答案之前建议对原帖进行编辑。 - Spontifixus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接