如何检测服务器端是否禁用了 cookie

How to detect server-side whether cookies are disabled

提问人:Oleksandr Yanovets 提问时间:2/10/2009 最后编辑:Rory O'KaneOleksandr Yanovets 更新时间:2/26/2022 访问量:93279

问:

如何在服务器(服务器端)检测浏览器中的cookie是否被禁用?可能吗?

详细说明:我正在服务器上处理 HTTP 请求。我想通过标头设置一个cookie。那时我需要知道 cookie 是由客户端浏览器设置的,还是我设置 cookie 的请求将被忽略。Set-Cookie

HTTP Cookie 服务器端

评论

0赞 Assaf Lavie 2/10/2009
哪里?在浏览器(客户端)中?还是在服务器中?(哪个服务器)
7赞 Assaf Lavie 2/10/2009
在服务器端代码中启用/禁用 DETECT cookie,是的。
0赞 balexandre 2/10/2009
您的意思是使用动态语言而不是 Javascript,Cookie 始终添加到客户端浏览器中,因此......没有服务器!

答:

3赞 Joonas Pulakka 2/10/2009 #1

尝试将某些内容存储到 cookie 中,然后读取它。如果您没有得到预期的结果,则 cookie 可能已被禁用。

评论

0赞 Tom Lianza 2/10/2009
很多网站都这样做。(在服务器上)无法确定是否在第一个请求上启用了 cookie,但您可以实施一个简短的重定向步骤来弄清楚。
61赞 Lawrence Dol 2/10/2009 #2

发送带有 cookie 集的重定向响应;在处理 cookie 的(特殊)重定向 URL 测试时 - 如果存在,则重定向到正常处理,否则重定向到错误状态。

请注意,这只能告诉您浏览器允许设置cookie,但不能告诉您设置了多长时间。我的 FF 允许我强制所有 cookie 进入“会话”模式,除非网站被专门添加到例外列表中 - 当 FF 关闭时,无论指定的服务器到期时间如何,此类 cookie 都将被丢弃。这就是我一直运行 FF 的模式。

评论

9赞 Lawrence Dol 5/23/2009
除了一些网站,其中一个确实是 SO。
18赞 Shoban 2/10/2009 #3

我认为没有直接的方法可以检查。最好的方法是在 cookie 中存储一个值,并尝试读取它们并决定是否启用 cookie。

41赞 balexandre 2/10/2009 #4

您可以使用 Javascript 来实现这一点

图书馆:

function createCookie(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toGMTString();
    }
    else expires = "";
    document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

function eraseCookie(name) {
    createCookie(name, "", -1);
}

function areCookiesEnabled() {
    var r = false;
    createCookie("testing", "Hello", 1);
    if (readCookie("testing") != null) {
        r = true;
        eraseCookie("testing");
    }
    return r;
}

要运行的代码:

alert(areCookiesEnabled());

记得

这仅在启用 Javascript 时有效!

评论

27赞 Adam 5/19/2010
问题是如何检测服务器端的cookie。您的代码在客户端运行。
2赞 balexandre 5/19/2010
服务器端 - 但他没有具体说明他使用的是什么服务器语言!但诀窍是一样的......写一个cookie,看看它是否在那里......如果是,则启用 Cookie,如果不是......禁用;)
14赞 Martijn 5/4/2011
他在服务器上使用什么语言并不重要。这个问题可以从HTTP请求/响应的角度来回答。
7赞 user207421 4/30/2012
该 Javascript 代码必须在浏览器中运行,以检测浏览器是否启用了 cookie。它不能在服务器端运行。
4赞 Chris 10/1/2012
@Adam - 尽管 OP 询问了服务器端,但如果您试图通知用户该站点需要启用 cookie 才能完全工作,则客户端 cookie 测试可以实现这一点(假设启用了 JavaScript)。
1赞 MSalters 2/10/2009 #5

cookie 是否“启用”的问题过于布尔。我的浏览器 (Opera) 具有每个站点的 cookie 设置。此外,该设置不是“是/否”。实际上,最有用的形式是“仅会话”,忽略服务器的到期日期。如果设置后直接测试,它就会在那里。明天,它不会。

此外,由于这是您可以更改的设置,因此即使测试 cookie 是否仍然存在,也只能告诉您在测试时的设置。我可能已经决定手动接受那个cookie。如果我继续收到垃圾邮件,我可以(有时也会)关闭该网站的 cookie。

评论

3赞 Oleksandr Yanovets 2/10/2009
好点子,但我只需要知道我的 Set-Cookie 标头是否会导致来自同一客户端的下一个请求将附带该 cookie。对我来说,它是永久性的还是仅供会话使用的并不重要。
18赞 thomasrutter 2/26/2009 #6

下面的答案是很久以前写的。现在,无论好坏,由于各个国家/地区的法律,除非必要,否则至少在用户有机会同意此类机制之前,不需要 cookie 已成为良好做法或法律要求。

最好只在用户尝试执行启动会话的操作(例如登录或将某些内容添加到购物车)时才执行此操作。否则,根据您的处理方式,您可能会阻止不支持 Cookie 的用户(或机器人)访问您的整个网站。

首先,服务器像往常一样检查登录数据 - 如果登录数据错误,用户将正常收到该反馈。如果它是正确的,那么服务器会立即响应一个cookie,并重定向到一个页面,该页面旨在检查该cookie - 它可能只是相同的URL,但在查询字符串中添加了一些标志。如果第二个页面未收到 cookie,则用户会收到一条消息,指出他们无法登录,因为其浏览器上禁用了 cookie。

如果您已经遵循登录表单的 Post-Redirect-Get 模式,则此设置和 cookie 检查不会添加任何其他请求 - cookie 可以在现有重定向期间设置,并由重定向后加载的目标进行检查。

现在,为什么我只在用户发起的操作之后进行cookie测试,而不是在每次页面加载时进行测试。我见过网站在每个页面上都实施了cookie测试,却没有意识到这会对搜索引擎试图抓取网站之类的事情产生影响。也就是说,如果用户启用了 cookie,则测试 cookie 将设置一次,因此他们只需要在他们请求的第一个页面上忍受重定向,从那时起就没有重定向了。但是,对于任何不返回 cookie 的浏览器或其他用户代理(如搜索引擎),每个页面都可能只会导致重定向。

检查 cookie 支持的另一种方法是使用 Javascript - 这样,不一定需要重定向 - 您可以编写一个 cookie 并几乎立即读取它以查看它是否被存储然后检索。这样做的缺点是它在客户端的脚本中运行 - 即如果您仍然希望有关是否支持cookie的消息返回到服务器,那么您仍然必须对其进行组织 - 例如使用Ajax调用。

对于我自己的应用程序,我通过在用户登录之前在登录屏幕上设置包含随机令牌的 cookie,并在用户提交登录详细信息时检查该令牌,从而对“登录 CSRF”攻击(CSRF 攻击的一种变体)实现一些保护。阅读有关Google的登录CSRF的更多信息。这样做的副作用是,当他们登录的那一刻,我可以检查该cookie的存在 - 不需要额外的重定向。

1赞 magritte 10/3/2011 #7

如果只想检查是否启用了会话 Cookie(在会话生存期内存存在的 Cookie),请在 web.config 文件中将会话模式设置为“自动检测”,然后 Asp.Net 框架将向客户端浏览器写入一个名为 AspxAutoDetectCookieSupport 的 Cookie。然后,可以在 Request.Cookies 集合中查找此 cookie,以检查客户端上是否启用了会话 Cookie。

例如,在您的 web.config 文件中设置:

<sessionState cookieless="AutoDetect" />

然后检查客户端上是否启用了 Cookie:

if (Request.Cookies["AspxAutoDetectCookieSupport"] != null)  { ... }

旁注:默认情况下,此值设置为 UseDeviceProfile,只要客户端支持 Cookie,它就会尝试将 Cookie 写入客户端,即使禁用了 Cookie。我觉得这是默认选项有点奇怪,因为它似乎毫无意义 - 会话将无法在客户端浏览器中禁用 cookie 并将其设置为 UseDeviceProfile,如果您支持不支持 cookie 的客户端的无 cookie 模式,那么为什么不使用自动检测并支持禁用它们的客户端的无 cookie 模式......

评论

1赞 David Moorhouse 11/9/2012
假设 ASP.NET 最初的问题是技术中立的
2赞 user1018130 11/8/2011 #8

我总是用这个:

navigator.cookieEnabled

根据 w3schools 的说法,“所有主流浏览器都支持 cookieEnabled 属性。

但是,当我使用表单时,这对我有用,我可以指示浏览器发送附加信息。

评论

0赞 Milan Gardian 5/27/2012
+1 来自我。投反对票有什么原因吗?这似乎是在 JavaScript 中检测 cookie 阻止的合理方法(对我来说在 Chrome 和 IE 中都有效)。
8赞 TJ VanToll 6/13/2012
我相信投反对票是因为这个问题专门询问了如何检测服务器端的支持。这是在客户端测试支持的最佳方式。
3赞 BryanH 1/9/2013
W3Schools 显然不是 HTML/Javascript/CSS/等信息的可靠来源
5赞 StuckOnSimpleThings 12/3/2013
这仅测试浏览器是否支持它。它不会测试它是否已启用。几乎每个浏览器都支持它,所以这似乎毫无价值。不好意思。
1赞 Broote 10/3/2012 #9

我使用的是上面“balexandre”答案的更简化版本。它尝试设置和读取会话 cookie,其唯一目的是确定是否启用了 cookie。是的,这也需要启用 JavaScript。因此,如果您愿意,您可能需要一个标签。

<script>
// Cookie detection
document.cookie = "testing=cookies_enabled; path=/";
if(document.cookie.indexOf("testing=cookies_enabled") < 0)
{
    // however you want to handle if cookies are disabled
    alert("Cookies disabled");
}
</script>
<noscript>
    <!-- However you like handling your no JavaScript message -->
    <h1>This site requires JavaScript.</h1>
</noscript>
-3赞 bren 2/11/2013 #10

使用导航器。CookieEnabled 表示已启用的 cookie(它将返回 true of false)和 Html 标记 noscript。顺便说一句,navigator.cookieEnabled 是 javascript,所以不要以 HTML 的形式输入它

评论

1赞 Evan M 12/31/2013
问题是关于服务器端检查,而不是客户端检查。
2赞 user2511210 11/13/2013 #11

检查此代码,它将对您有所帮助。

<?php
session_start();

function visitor_is_enable_cookie() {
    $cn = 'cookie_is_enabled';
    if (isset($_COOKIE[$cn]))
        return true;
    elseif (isset($_SESSION[$cn]) && $_SESSION[$cn] === false)
        return false;

    // saving cookie ... and after it we have to redirect to get this
    setcookie($cn, '1');
    // redirect to get the cookie
    if(!isset($_GET['nocookie']))
        header("location: ".$_SERVER['REQUEST_URI'].'?nocookie') ;

    // cookie isn't availble
    $_SESSION[$cn] = false;
    return false;
}

var_dump(visitor_is_enable_cookie());
-1赞 user3211045 1/20/2014 #12
<?php   session_start();
if(SID!=null){
  echo "Please enable cookie";
}
?>
0赞 Zameer Khan 6/6/2014 #13

该属性返回一个 Boolean 值,该值指定是否在浏览器中启用 CookiecookieEnabled

<script>
if (navigator.cookieEnabled) {
    // Cookies are enabled
}
else {
    // Cookies are disabled
}
</script>

评论

0赞 ZiggyTheHamster 11/8/2016
OP想知道如何在服务器端检测它。
0赞 Steve 10/23/2019
显然,您必须以适合您的应用程序的方式将该信息返回到服务器。应该清楚的是,如果不与浏览器交互,就无法确定浏览器是否启用了 Cookie。
2赞 buycanna.io 7/19/2018 #14

NodeJS - 服务器端 - Cookie 检查重定向 中间件 - Express Session/Cookie 解析器

依赖

var express = require('express'),
    cookieParser = require('cookie-parser'),
    expressSession = require('express-session')

中间件

return (req, res, next) => {
  if(req.query.cookie && req.cookies.cookies_enabled)
    return res.redirect('https://yourdomain.io' + req.path)
  if(typeof(req.cookies.cookies_enabled) === 'undefined' && typeof(req.query.cookie) === 'undefined') {
    return res.cookie('cookies_enabled', true, {
      path: '/',
      domain: '.yourdomain.io',
      maxAge: 900000, 
      httpOnly: true,
      secure: process.env.NODE_ENV ? true : false
    }).redirect(req.url + '?cookie=1')
  }
  if(typeof(req.cookies.cookies_enabled) === 'undefined') {
    var target_page = 'https://yourdomain.io' + (req.url ? req.url : '')
    res.send('You must enable cookies to view this site.<br/>Once enabled, click <a href="' + target_page + '">here</a>.')
    res.end()
    return
  }
  next()
}