检查是否启用了cookie


77

我正在一个需要JavaScript和会话的页面上工作。我已经有代码来警告用户是否禁用了javascript。现在,我想处理禁用cookie的情况,因为会话ID存储在cookie中。

我只想到了几个主意:

  1. 将会话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>

3
可以在链接中嵌入会话ID,但是很麻烦。这意味着您要向搜索引擎显示会话ID。这意味着共享链接的人可以登录同一会话。
TRiG 2011年

您能否将问题的标题更新为以下内容:检查是否已使用javascript启用cookie?
imme 2012年

那不是问题的实质,请阅读整个问题。JavaScript就是问题的答案。
steveo225

Answers:


88

的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;

的PHP

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

somescript.php

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

check.php

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

16
如果您可以扩展答案以解释这些链接的另一端的某些技术,并保留这些链接以供参考,那将非常有帮助。否则,答案就会因链接腐烂而处于危险之中,而这些链接类型通常会突然消失。谢谢。
2012年

1
重定向是不必要的,另请参阅下面的答案。您可以检查cookie是否已启用,而无需“重新加载”。
Codebeat 2014年

第二个链接中是否存在该恶意软件?“ PHP和Cookies,很好的结合!” 为什么要我安装令人毛骨悚然的浏览器扩展?
米格尔·瓦伦西亚

@MiguelValencia:该站点似乎不再存在,我已删除了链接
Sascha Galley

感谢您清晰明确的回答。近代化现在建议不要使用navigator.cookieenabled:github.com/Modernizr/Modernizr/blob/master/feature-detects/...
joshterrell805

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";

2
这是迄今为止最简单,最好的示例!一个评论:在执行此操作之前,请先检查会话是否已经开始,并在完成测试时将其保持启用状态。
Codebeat

请在此页面上查看我修改后的功能更强大的帖子!
2013年

11
这仅在刷新后有效!在第一次加载时,它总是将Cookie设置为OFF,因为如果不与浏览器交换至少一个请求,就无法测试是否启用了Cookie。Cookie是每个请求的标头信息的一部分,而Cookie操作是通过响应标头完成的。没有办法解决。
帕维尔2014年

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;
    }

用法:

if( suGetClientCookiesEnabled())
 { echo 'Cookies are enabled!'; }
else { echo 'Cookies are NOT enabled!'; }

重要说明: 该函数在没有正确设置的情况下会临时修改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!'; }

Erwinus,能否请您说“当您开始一个会话并且php ini设置session.use_cookies的值不正确时,它可能出错”,进一步解释您的意思。哪个值可能不正确?我正在尝试实现您的想法,但不确定我需要将我的php ini设置为...谢谢!
塞巴斯蒂安

2
@Sebastian:在开始会话之前,您要检查是否启用了cookie并且session.use_cookies是FALSE,例如,它可能会失败。为确保其正常工作,必须在开始任何会话之前先调用testfunction suGetClientCookiesEnabled()。这对您来说清楚/可以理解吗?希望能有所帮助。
Codebeat 2013年

不幸的是,它在第​​一次调用站点时不起作用,例如,以隐身模式尝试。 第一次调用一个网站,你可以期望$ _COOKIE [“PHPSESSID”]被设置和证明Cookie已启用,但在第一个调用它是空的-用你的方法,你还是每次都获得一个新的会话ID ,它什么也没证明。
罗布2014年

@Rob:我认为你做错了。开始任何其他会话之前,必须检查cookie是否已启用。另请参见对塞巴斯蒂安的评论和答案中的“重要说明”。出于安全原因,最好重命名会话名称:ini_set('session.name','您的名字')和ini_set('session.use_only_cookies',true); 和ini_set('session.use_trans_sid',false);
Codebeat

3
@Erwinus-您没有尝试?为了证明我的意思,请尝试:1.使用您的答案中的代码创建一个php文件。2.在chrome中打开一个新的隐身窗口。3.直接浏览至php测试文件。首次通话说:“未启用Cookie!”。第二个电话说:“启用Cookie!”。我只是指出这一点。不幸的是,这会使您的代码浪费一些时间,因为在第二次调用中,您可以检查是否填充了$ _COOKIE ['PHPSESSID']-如果已填充,则启用了cookie。
罗布

7

一种透明,干净且简单的方法,使用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);
});

(可以将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();
    }
}

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

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

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


1
这种方法适用于大多数设备,但如果禁用了javascript,将会发疯
ppp 2014年

6

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

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

有可能,请参阅我的答案
Codebeat 2013年

谢谢马丁。我只是学习并欣赏这种构象。由于您的第一点,我发现能够在PHP脚本中设置或读取cookie的整个想法非常令人困惑。要阅读PHP手册,您会认为,只要在<html>标记之前执行setcookie(),就可以在以后立即读取一行代码,这似乎几乎是不可能的。我,除非我缺少重要的东西。坦白说,最后一点出现的机制对我来说仍然是个谜。我希望我能找到关于其工作原理的明确解释。
兰迪

2

您可以进行Ajax调用(注意:此解决方案需要JQuery):

example.php

<?php
    setcookie('CookieEnabledTest', 'check', time()+3600);
?>

<script type="text/javascript">

    CookieCheck();

    function CookieCheck()
    {
        $.post
        (
            'ajax.php',
            {
                cmd: 'cookieCheck'
            },
            function (returned_data, status)
            {
                if (status === "success")
                {
                    if (returned_data === "enabled")
                    {
                        alert ("Cookies are activated.");
                    }
                    else
                    {
                        alert ("Cookies are not activated.");
                    }
                }
            }
        );
    }
</script>

ajax.php

$cmd = filter_input(INPUT_POST, "cmd");

if ( isset( $cmd ) && $cmd == "cookieCheck" )
{
    echo (isset($_COOKIE['CookieEnabledTest']) && $_COOKIE['CookieEnabledTest']=='check') ? 'enabled' : 'disabled';
}

结果,出现一个警告框,显示是否启用了cookie。当然,您不必显示警报框,您可以从此处采取其他步骤来处理已停用的Cookie。


1

的JavaScript

您可以使用JavaScript创建cookie并检查其是否存在:

//Set a Cookie`
document.cookie="testcookie"`

//Check if cookie exists`
cookiesEnabled=(document.cookie.indexOf("testcookie")!=-1)? true : false`

或者您可以使用jQuery Cookie插件

//Set a Cookie`
$.cookie("testcookie", "testvalue")

//Check if cookie exists`
cookiesEnabled=( $.cookie("testcookie") ) ? true : false`

p

setcookie("testcookie", "testvalue");

if( isset( $_COOKIE['testcookie'] ) ) {

}

不确定Php是否可以正常运行,因为我无法测试它。


2
PHP代码无法正常工作。您需要重新加载页面,以便浏览器发送第二个HTTP请求。如果第二个HTTP请求具有从第一个HTTP请求中设置的cookie,则启用cookie。
戴夫·贾维斯

0

很容易检测是否启用了cookie:

  1. 设置一个cookie。
  2. 得到饼干

如果可以获取设置的cookie,cookie则启用,否则不启用。

顺便说一句:对,这是个坏主意Embedding the session id in the links and forms,对SEO则不利。在我看来,人们不希望启用Cookie并不是很常见


1
仅供参考,您实际上会感到惊讶。我有一个Firefox插件,该插件可以阻止除白名单上的域之外的所有cookie,并且注意到许多用户都在效仿。实际上,这就是引发问题的原因:我无法使用该表格,也无法弄清楚为什么起初,大声笑。
steveo225

您不能使用表格是什么意思?无法将jsessionid嵌入表单?
James.Xu 2011年

该表单是一个多提交系统,未启用Cookie,因此页面始终从头开始而不是继续,因为无法设置会话。
steveo225

在欧洲,有一项新的Cookie法规,它害怕分配人启用Cookie,因为网站必须要求接受Cookie。这个问题激怒了访客分配,因为他们完全关闭了cookie。您说:“不是很常见”,这是正确的,因为他们不知道它在那里。由于这项愚蠢的法律,更多的人对此有所了解,并在知道如何做时将其关闭。
Codebeat

0

这是一个非常有用且轻巧的javascript插件来完成此任务:js-cookie

Cookies.set('cookieName', 'Value');
      setTimeout(function(){
        var cookieValue =  Cookies.get('cookieName');
        if(cookieValue){
           console.log("Test Cookie is set!");
        } else {
           document.write('<p>Sorry, but cookies must be enabled</p>');
        }
        Cookies.remove('cookieName');
      }, 1000);

在所有浏览器中均可使用,可接受任何字符。


0

Cookies是客户端的,无法使用PHP进行正确测试。这是基准,每种解决方案都是解决该问题的方法。

这意味着如果您正在寻找解决Cookie问题的方法,那么您的方法就错误。不要使用PHP,请使用Java语言等客户端语言。

可以通过PHP使用Cookie吗?是的,但是您必须重新加载才能使PHP的设置“可见”。

例如:是否可以测试浏览器是否可以使用纯PHP设置Cookies。唯一正确的答案是“否”。

您可以阅读已经设置的Cookie:'YES'使用预定义的$ _COOKIE(启动PHP-App之前的设置副本)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.