检查cookie是否已启用

ste*_*225 65 javascript php session-cookies

我正在开发一个需要javascript和会话的页面.如果禁用了javascript,我已经有代码警告用户.现在,我想处理禁用cookie的情况,因为会话ID存储在cookie中.

我想到了几个想法:

  1. 在会话ID和表单中嵌入会话ID
  2. 警告用户如果禁用了cookie,他们必须启用cookie(需要帮助检测是否禁用了cookie)

解决这个问题的最佳方法是什么?谢谢

编辑

根据链接的文章,我提出了自己的方法,并认为我会分享,其他人可能会使用它,也许我会得到一些批评.(假设您的PHP会话存储在名为的cookie中PHPSESSID)

<div id="form" style="display:none">Content goes here</div>
<noscript>Sorry, but Javascript is required</noscript>
<script type="text/javascript"><!--
if(document.cookie.indexOf('PHPSESSID')!=-1)
   document.getElementById('form').style.display='';
else
   document.write('<p>Sorry, but cookies must be enabled</p>');
--></script>
Run Code Online (Sandbox Code Playgroud)

Sas*_*ley 75

JavaScript的

在JavaScript中,您可以对cookieEnabled属性进行简单测试,该属性在所有主流浏览器中都受支持.如果您处理较旧的浏览器,则可以设置cookie并检查它是否存在.(借用Modernizer):

if (navigator.cookieEnabled) return true;

// set and read cookie
document.cookie = "cookietest=1";
var ret = document.cookie.indexOf("cookietest=") != -1;

// delete cookie
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";

return ret;
Run Code Online (Sandbox Code Playgroud)

PHP

在PHP中,它相当"复杂",因为您必须刷新页面或重定向到另一个脚本.在这里,我将使用两个脚本:

somescript.php

<?php
session_start();
setcookie('foo', 'bar', time()+3600);
header("location: check.php");
Run Code Online (Sandbox Code Playgroud)

check.php

<?php echo (isset($_COOKIE['foo']) && $_COOKIE['foo']=='bar') ? 'enabled' : 'disabled';
Run Code Online (Sandbox Code Playgroud)

  • 如果您可以扩展您的答案以解释这些链接的另一端的一些技术并保留[链接以供参考](http://meta.stackexchange.com/q/8259),那将非常有用.如果不这样做会使链接腐烂的答案处于危险之中,那些类型的链接通常会突然消失.谢谢. (16认同)

小智 17

但要检查是否使用isset($ _ COOKIE ["cookie"])启用了cookie,您必须刷新.我正在这样做(基于cookie的会话:)

session_start();
$a = session_id();
session_destroy();

session_start();
$b = session_id();
session_destroy();

if ($a == $b)
    echo"Cookies ON";
else
    echo"Cookies OFF";
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于刷新后!在第一次加载时,它始终显示_Cookies OFF_,因为有_no way_来测试是否启用了cookie而没有与浏览器交换至少一个请求.Cookie是每个请求的头信息的一部分,Cookie操作是通过响应头完成的.没有办法绕过它. (11认同)
  • 到目前为止,这是最简单,最好的例子!一条评论:在完成测试之前,首先检查会话是否已经启动,并在完成测试后保持启用. (2认同)

Cod*_*eat 11

回答一个老问题,这个新帖子发布于 2013 年 4 月 4 日

为了完成@misza 的回答,这里有一种高级方法来检查 cookie 是否已启用而无需重新加载页面。@misza 的问题在于,当 php ini 设置session.use_cookies不正确时,它并不总是有效。此外,该解决方案不会检查会话是否已启动。

我制作了这个功能并在不同情况下对其进行了多次测试,并且做得很好。

    function suGetClientCookiesEnabled() // Test if browser has cookies enabled
    {
      // Avoid overhead, if already tested, return it
      if( defined( 'SU_CLIENT_COOKIES_ENABLED' ))
       { return SU_CLIENT_COOKIES_ENABLED; }

      $bIni = ini_get( 'session.use_cookies' ); 
      ini_set( 'session.use_cookies', 1 ); 

      $a = session_id();
      $bWasStarted = ( is_string( $a ) && strlen( $a ));
      if( !$bWasStarted )
      {
        @session_start();
        $a = session_id();
      }

   // Make a copy of current session data
  $aSesDat = (isset( $_SESSION ))?$_SESSION:array();
   // Now we destroy the session and we lost the data but not the session id 
   // when cookies are enabled. We restore the data later. 
  @session_destroy(); 
   // Restart it
  @session_start();

   // Restore copy
  $_SESSION = $aSesDat;

   // If no cookies are enabled, the session differs from first session start
  $b = session_id();
  if( !$bWasStarted )
   { // If not was started, write data to the session container to avoid data loss
     @session_write_close(); 
   }

   // When no cookies are enabled, $a and $b are not the same
  $b = ($a === $b);
  define( 'SU_CLIENT_COOKIES_ENABLED', $b );

  if( !$bIni )
   { @ini_set( 'session.use_cookies', 0 ); }

  //echo $b?'1':'0';
  return $b;
    }
Run Code Online (Sandbox Code Playgroud)

用法:

if( suGetClientCookiesEnabled())
 { echo 'Cookies are enabled!'; }
else { echo 'Cookies are NOT enabled!'; }
Run Code Online (Sandbox Code Playgroud)

重要提示: 该功能在没有正确设置时临时修改PHP的ini设置,并在未启用时恢复它。这仅用于测试是否启用了 cookie。当您启动会话并且 php ini 设置 session.use_cookies 的值不正确时,它可能会出错。为确保会话正常工作,请在开始会话之前检查和/或设置它,例如:

   if( suGetClientCookiesEnabled())
     { 
       echo 'Cookies are enabled!'; 
       ini_set( 'session.use_cookies', 1 ); 
       echo 'Starting session';
       @start_session(); 

     }
    else { echo 'Cookies are NOT enabled!'; }
Run Code Online (Sandbox Code Playgroud)

  • @Erwinus - 你没试过?为了证明我所说的,请尝试: 1. 使用您的答案中的代码创建一个 php 文件 2. 在 chrome 中打开一个新的*隐身窗口* 3. 直接浏览到 php 测试文件。第一个电话说:“Cookie 未启用!”。第二个电话说:“Cookies 已启用!”。我只是指出这一点。不幸的是,它使您的代码有点浪费时间,因为在第二次调用时,您可以检查 $_COOKIE['PHPSESSID'] 是否已填充 - 如果是,则启用 cookie。 (3认同)
  • @Sebastian:当您在检查 cookie 是否启用并且 session.use_cookies 为 FALSE 之前开始会话时,它可能会失败。为了确保它正常工作,您必须在启动任何会话之前先调用测试函数 suGetClientCookiesEnabled()。这对你来说清楚/可以理解吗?希望它有帮助。 (2认同)

小智 6

您不能在同一页面的加载集中检查是否设置了cookie,您必须执行重新加载页面:

  • PHP在Server上运行;
  • 客户端的cookie.
  • cookie仅在加载页面期间发送到服务器.
  • 刚刚创建的cookie尚未发送到服务器,只会在下次加载页面时发送.


小智 6

一种透明,干净且简单的方法,使用PHP检查cookie可用性并利用AJAX透明重定向,因此不会触发页面重新加载.它也不需要会话.

客户端代码(JavaScript)

function showCookiesMessage(cookiesEnabled) {
    if (cookiesEnabled == 'true')
        alert('Cookies enabled');
    else
        alert('Cookies disabled');
}

$(document).ready(function() {
    var jqxhr = $.get('/cookiesEnabled.php');
    jqxhr.done(showCookiesMessage);
});
Run Code Online (Sandbox Code Playgroud)

(JQuery AJAX调用可以用纯JavaScript AJAX调用替换)

服务器端代码(PHP)

if (isset($_COOKIE['cookieCheck'])) {
    echo 'true';
} else {
    if (isset($_GET['reload'])) {
        echo 'false';
    } else {
        setcookie('cookieCheck', '1', time() + 60);
        header('Location: ' . $_SERVER['PHP_SELF'] . '?reload');
        exit();
    }
}
Run Code Online (Sandbox Code Playgroud)

第一次调用脚本时,会设置cookie并且脚本会告诉浏览器重定向到自身.浏览器透明地完成它.不会发生页面重新加载,因为它是在AJAX调用范围内完成的.

第二次,当通过重定向调用时,如果接收到cookie,则脚本响应HTTP 200(字符串为"true"),因此showCookiesMessage调用该函数.

如果第二次调用该脚本(由"reload"参数标识)并且未收到cookie,则它将使用字符串"false"响应HTTP 200,并showCookiesMessage调用该函数.