检查 Cookie 是不是存在

Posted

技术标签:

【中文标题】检查 Cookie 是不是存在【英文标题】:Check if Cookie Exists检查 Cookie 是否存在 【发布时间】:2012-10-15 01:05:35 【问题描述】:

Stack Overflow 上的快速搜索中,我看到人们建议使用以下方法来检查 cookie 是否存在:

HttpContext.Current.Response.Cookies["cookie_name"] != null

或(在Page 类中):

this.Response.Cookies["cookie_name"] != null

但是,当我尝试使用索引器(或 Cookies.Get 方法)检索一个不存在的 cookie 时,它​​似乎实际上 创建 一个具有该名称的“默认”cookie 并返回因此,无论我使用什么 cookie 名称,它都不会返回 null。 (甚至更糟 - 创建一个不需要的 cookie)

我在这里做错了什么,还是有其他方法可以简单地通过名称检查特定 cookie 的存在?

【问题讨论】:

【参考方案1】:

有时您仍然需要知道 Cookie 是否存在于 Response 中。然后你可以检查cookie key是否存在:

HttpContext.Current.Response.Cookies.AllKeys.Contains("myCookie")

更多信息可以在here找到。

就我而言,我必须在 Global.asax 的 Application_EndRequest 方法中修改响应 Cookie。如果 Cookie 不存在,我不会碰它:

string name = "myCookie";
HttpContext context = ((HttpApplication)sender).Context;
HttpCookie cookie = null;

if (context.Response.Cookies.AllKeys.Contains(name))

    cookie = context.Response.Cookies[name];


if (cookie != null)

    // update response cookie

【讨论】:

如果您需要检查响应中生成的 cookie,这是正确的答案。 如果您的 AllKeys 集合不包含 Contains 函数,您可以包含 LINQ (using System.Linq)。 第一个条件语句中的sender 是什么。它在我的控制器方法中显示错误。 你应该使用 Request 而不是 Response。【参考方案2】:

这里有很多正确的答案取决于你想要完成的事情;这是我提供全面答案的尝试:

RequestResponse 对象都包含Cookies 属性,即HttpCookieCollection 对象。

Request.Cookies:

此集合包含从客户端收到的 cookie 此集合是只读的 如果您尝试访问此集合中不存在的 cookie,您将收到 null 值。

Response.Cookies:

此集合仅包含服务器在当前请求期间添加的 cookie。 这个集合是可写的 如果您尝试访问此集合中不存在的 cookie,您将收到一个新的 cookie 对象;如果您尝试访问 DOES NOT 的 cookie 存在于 Request.Cookies 集合中,它将被添加(但如果 Request.Cookies 对象已经包含具有相同键的 cookie,即使它是值已过时,它不会被更新以反映 Response.Cookies 集合中新创建的 cookie 的更改。

解决方案


如果要检查客户端是否存在 cookie,请执行以下操作之一

Request.Cookies["COOKIE_KEY"] != null Request.Cookies.Get("COOKIE_KEY") != null Request.Cookies.AllKeys.Contains("COOKIE_KEY")

如果您想检查服务器在当前请求期间添加的 cookie 是否存在,请执行以下操作:

Response.Cookies.AllKeys.Contains("COOKIE_KEY")(见here)

正在尝试通过以下方法之一检查服务器在当前请求期间添加的 cookie...

Response.Cookies["COOKIE_KEY"] != null Response.Cookies.Get("COOKIE_KEY") != null(见here)

...将导致在Response.Cookies 集合中创建一个cookie,并且状态将评估为true

【讨论】:

感谢您的总结。 这是一个很好的总结,与我看到的行为相对应。关于响应的最后一点 - 索引器、getter 和列表 - 是否记录在任何地方?他们可以改变这种行为,我们的代码就会失败。 我找到了调用Response.Cookies.Get("COOKIE_KEY") 的文档,并使用链接更新了答案。 Response.Cookies.Item[String] 的文档没有说明创建新 cookie,但是,我相信它很可能只是在后台调用 Response.Cookies.Get(String)Response.Cookies.AllKeys.Contains(String) 的文档也没有具体提到这种行为,但我怀疑这是因为 AllKeys 只是所有现有 cookie 的 String[],因此 Contains(String) 方法在另一个库中实现。【参考方案3】:

Response.Cookies 包含将发送回浏览器的 cookie。如果您想知道是否存在 cookie,您可能应该查看Request.Cookies

无论如何,要查看cookie是否存在,您可以检查Cookies.Get(string)但是,如果您在 Response 对象上使用此方法并且 cookie不存在,则将创建该 cookie。

请参阅 MSDN 参考以获取 HttpCookieCollection.Get Method (String)

【讨论】:

使用Request 而不是Response seems 以我想要的方式工作。谢谢(两个答案几乎相同,但你先回答了 Cookies.Get(string) 的链接文档中的注释表明“如果指定的 cookie 不存在,则此方法会创建一个具有该名称的新 cookie。” @MichaelPetito 虽然文档这么说,但我发现如果找不到它会返回 null 。我相信如果不存在则创建仅在使用响应时适用。如果 Request.Cookies 则 Get 返回 null。您现在可以在该文档上看到一些关于此的用户 cmets。 为什么假设 OP 不想知道响应 cookie 是否存在?也许他们想知道响应中是否已经添加了 cookie。 Get 在问题的上下文中不起作用。 Aaron,不管文档怎么说... get 方法的代码是: HttpCookie cookie = (HttpCookie) this.BaseGet(name); if (cookie == null && this._response != null) cookie = new HttpCookie(name); this.AddCookie(cookie, true); [...] 显然新的 cookie 将被返回,所以只要检查请求是好的,我不会指望收集行为【参考方案4】:

您需要使用HttpContext.Current.Request.Cookies,而不是Response.Cookies

旁注:cookie 被复制到Response.Cookies.Add 上的请求,这使得检查它们中的任何一个对于新添加的 cookie 的行为相同。但是传入的 cookie 永远不会反映在 Response 中。

此行为记录在HttpResponse.Cookies 属性中:

使用 HttpResponse.Cookies 集合添加 cookie 后,即使尚未将响应发送到客户端,该 cookie 也会立即在 HttpRequest.Cookies 集合中可用。

【讨论】:

谢谢,使用Request 正是我所需要的。 +1 这是我发现的关于 cookie 复制行为的唯一文档 - 谢谢!太恶心了。 是的,并且带有“旁注:”的复制只发生在新的 cookie 上。如果您在响应中更新 cookie,如果 cookie 已经在请求中,它将不会更新请求。如果您有一个框架在同一个请求中多次修改 cookie,这可能会让人头疼。【参考方案5】:
public static class CookieHelper

    /// <summary>
    /// Checks whether a cookie exists.
    /// </summary>
    /// <param name="cookieCollection">A CookieCollection, such as Response.Cookies.</param>
    /// <param name="name">The cookie name to delete.</param>
    /// <returns>A bool indicating whether a cookie exists.</returns>
    public static bool Exists(this HttpCookieCollection cookieCollection, string name)
    
        if (cookieCollection == null)
        
            throw new ArgumentNullException("cookieCollection");
        

        return cookieCollection[name] != null;
    

用法:

Request.Cookies.Exists("MyCookie")

【讨论】:

我在Cookie 类中找不到Exists 方法 这段代码为 Cookie 类创建了一个扩展,它添加了“Exists”方法。扩展真的很酷。 仍然,[] 运算符的代码调用 Get 方法,如果没有找到,则创建一个新的 cookie,这意味着结果永远不会为空,只是一个空 cookie(在 HttpResponse 的情况下) 根据最后的评论,您的退货声明应为return cookieCollection.AllKeys.Contains(name);【参考方案6】:

抱歉,没有足够的代表添加评论,但来自 zmbq 的回答:

无论如何,要查看cookie是否存在,可以检查Cookies.Get(string),这不会修改cookie集合。

可能不完全正确,因为 Cookies.Get(string) 实际上会创建一个具有该名称的 cookie,如果它不存在的话。 但是,正如他所说,您需要查看 Request.Cookies,而不是 Response.Cookies 所以,类似:

bool cookieExists = HttpContext.Current.Request.Cookies["cookie_name"] != null;

【讨论】:

这不正确,它会返回 null:“Cookies.Get(string) 实际上会创建一个具有该名称的 cookie” 我已经了解到,如果不存在则创建适用于 Response.Cookies,但不适用于 Request.Cookies。【参考方案7】:

您可以执行以下操作来找出 cookie 的值:

Request.Cookies[SESSION_COOKIE_NAME].Value

【讨论】:

以上是关于检查 Cookie 是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

jQuery检查Cookie是不是存在,如果不存在则创建它

检查 PHP cookie 是不是存在,如果没有设置它的值

检查 cookie 是不是不包含指定的内容 NGINX

如何检查ColdFusion 2016中是否存在cookie?

php创建了cookie怎么判断的是不是存在和cookie的值

如何检查用户是不是通过 Laravel 上的 cookie 会话进行身份验证?