【问题标题】:Check if cookies are enabled without setting GET parameter or sessions in PHP检查是否启用了 cookie 而不在 PHP 中设置 GET 参数或会话
【发布时间】:2013-02-06 17:24:06
【问题描述】:

很像Detect if cookies are enabled in PHPCheck if cookies are enabled 中提出的问题,我想知道是否启用了cookie。

不过,我正在努力使这对用户尽可能透明,因此我对在我的 URL 中附加一些“cookietest=1”参数不感兴趣。

我知道我可以重定向回用户最初输入的页面,取消设置“cookietest=1”GET 参数,然后通过会话告诉原始页面是否禁用了 cookie,但是...

我目前正在使用 CodeIgniter,不想弄乱 CodeIgniter 会话,因此不使用 PHP 会话来存储 cookie 启用/禁用状态。

我实际上不确定使用 PHP 会话是否会弄乱 CodeIgniter 会话,但即使不是,我仍然想知道是否有一些巧妙的解决方案,可以在不设置的情况下进行 cookie 检查一个 GET 参数或使用会话(但是重定向很好)?

更新

看来我需要澄清一点:

我想知道客户端是否启用了cookies。我已经尝试过我链接到的问题中描述的方法,即:

  1. 设置 cookie。
  2. 重定向到检查 cookie PHP 页面或使用“cookietest=1”GET 参数的同一页面。
  3. 查看 cookie 是否仍然设置:如果是 => 万岁,cookie 正在工作!否则 => 嘘,cookie 被禁用。

我要问的是是否可以在不设置 GET 参数的情况下执行此操作(因为这在 URL 中可见)。该问题的答案是“是的,如果您使用 PHP 会话”。

然后我的下一个问题是:是否可以不设置 GET 参数并且不使用 PHP 会话?

【问题讨论】:

  • 仅供参考 CodeIgniter 实际上并不使用 cookie,它存储会话密钥,所有数据都存储在会话数据库表中。
  • 但它是否使用原生 PHP 会话,如果我开始设置会话变量,可能会以某种方式搞砸,而不是什么?
  • @Dunhamzzz CodeIgniter “确实”使用 cookie,但默认情况下仅存储会话的哈希键。除此之外,您可以将 CodeIgniter 配置为使用基于您在application/config/config.php中设置的 32 位 md5 哈希的加密 cookie@

标签: php cookies


【解决方案1】:

基本知识:在您向客户端发送一个 cookie 并从他那里收到相同的信息之前,您无法知道用户是否启用了 cookie。

所以流程:

  • 客户请求
  • 服务器响应(+ cookie)
  • 客户端请求(+ cookie)

无法避免

您可以使用一些测试请求(ajax、图像等)跟踪是否启用了 cookie

例如,您可以使用简单的 1px 图像或从您的 php 脚本提供的任何徽标图像,并且您可以跟踪是否启用了 cookie。

所以现在的流程是:

  • 客户请求
  • 服务器响应 HTML(+ cookie)
  • 客户端请求远程页面资源(js、img、css)(+ cookie)
  • 请求页面资源的服务器响应

类似

<?php 
    // domain.com/some.js
    if (isset($_COOKIE['test']))
         $_SESSION['cookies_enabled'] = true;

    echo <<JS
    <someJS code or nothing>
    JS;
 ?>

【讨论】:

  • 虽然这适用于网页 - 如果初始请求已经是 ajax 请求怎么办?
  • 可以,只关心httponly标志
【解决方案2】:

前段时间我对此进行了很多研究,似乎每个方面都有其缺陷。我还考虑到的一件事是,如果用户要更新页面或通过后退按钮返回页面,cookie 检查将如何工作。

显然,为了让服务器查看客户端是否接受 cookie,客户端必须在服务器尝试设置 cookie 后发送额外的HTTP request,服务器在其中查找指示客户端的 cookie 标头接受 cookie(无标头 = 不接受 cookie)。这个额外的请求可以重定向到另一个页面(参见使用$_GET 参数作为标志的常用方法,说明是否尝试设置cookie)但重要的是它实际上只是另一个HTTP要求。我最终做的是将整个页面包装在HTML FRAMESET

<?php
    setcookie('test', 1, time() + 3600);
    echo '<HTML>
        <HEAD>
            <TITLE>
            </TITLE>
        </HEAD>
        <frameset rows="100%" cols="100%">
            <frame src="next.php">
        </frameset>
    </HTML>';
?>

...然后在next.php 的附加HTTP request 中,我知道如果客户端已接受cookie,请求中将包含一个cookie 标头,因此我不必使用$_GET 参数作为表明这一点的标志。 Next.php 因此看起来像:

<?php
    if(count($_COOKIE) > 0){
        //Set some variable that indicates to the rest of the script that cookies 
        //are enabled.
    }
    else {
        //Set some variable indicating that cookies are disabled
    }
    //Output the rest of the script and HTML code to be displayed
?>

我想过做同样的事情,但是从IMG标签而不是FRAMESET发送额外的HTTP request,但我遇到了麻烦,我将如何通过图像向父脚本指示cookie是否是设置与否,因此我最终这样做了。我在这种方法中看到的唯一缺陷是,如果用户在框架内右键单击并选择仅更新框架(而不是整个页面),那么框架将错误地声称 cookie 被禁用,但与所有的缺点相比其他方式,我认为这是可以接受的。

编辑:我还应该补充一点,我在没有 Javascript 的情况下也这样做了。

【讨论】:

    【解决方案3】:

    我会使用 php.ini 设置来找出这些东西。 可能是这样的:

    if (ini_get("session.use_cookies") == 1) {
      print "cookies enabled";
    }
    

    【讨论】:

    • 这只会告诉我是否启用了服务器端的 cookie。我已经澄清了我要说的客户端问题。
    【解决方案4】:

    虽然您可以检查 php 是否启用了 cookie,但一个非常简单的测试就是设置一个 cookie,然后尝试读取它。

    如果您成功阅读它,它就起作用了。 如果客户端不允许使用 cookie,这也会通知您。

    【讨论】:

    • 这是我已经测试过的,但我正在寻找一种“更漂亮”的方式来做到这一点。我已经更新了我的问题并进行了一些澄清。
    • 虽然看起来很丑,但它是最简单的检查方法。你总是可以把它放到一个函数中然后检查吗?
    • 只有在页面重新加载后才能获取 Cookie,因此此方法始终会导致 cookie 被禁用 - 因此整个重定向都使用 GET 参数,如我的说明中所述。
    猜你喜欢
    • 2011-12-09
    • 2014-06-15
    • 2023-03-12
    • 2012-03-10
    • 2012-05-11
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    相关资源
    最近更新 更多