86

I am working on a page that requires javascript and sessions. I already have code to warn the user if javascript is disabled. Now, I want to handle the case where cookies are disabled, as the session id is stored in cookies.

I have thought of just a couple ideas:

  1. Embedding the session id in the links and forms
  2. Warn the user they must enable cookies if they are disabled (would need help detecting if cookies are disabled)

What is the best way to approach this? Thanks

EDIT

Based on the articles linked, I came up with my own approach and thought I would share, somebody else might be able to use it, maybe I will get a few critiques. (Assumes your PHP session stores in a cookie named 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>
steveo225
  • 11,394
  • 16
  • 62
  • 114
  • 3
    Embedding the session id in links is possible, but messy. It means you're presenting session ids to search engines. It means people who share links may log into the same session. – TRiG Jul 12 '11 at 12:05
  • could you update the question's title to something like: Check if cookies are enabled with javascript ? – imme Sep 10 '12 at 00:32
  • That is not what the question was about, please read the entire question. JavaScript is simply how the question was answered. – steveo225 Sep 10 '12 at 17:41

10 Answers10

101

JavaScript

In JavaScript you simple test for the cookieEnabled property, which is supported in all major browsers. If you deal with an older browser, you can set a cookie and check if it exists. (borrowed from 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

In PHP it is rather "complicated" since you have to refresh the page or redirect to another script. Here I will use two scripts:

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';
Sascha Galley
  • 15,711
  • 5
  • 37
  • 51
  • 16
    It would be really helpful if you could expand your answer to explain some of the techniques at the other ends of those links and keep the [links for reference](http://meta.stackexchange.com/q/8259). Failing to do that leaves the answer at risk from link rot, and those types of links are typically the sort that suddenly go away. Thanks. – Kev Sep 26 '12 at 00:34
  • 1
    Redirect not necessary, see also my answer below. You are able to check cookies are enabled without 'reloading'. – Codebeat Jul 07 '14 at 23:28
  • Is that malware in the second link? "PHP and Cookies, A Good Mix!" Why's it asking me to install a creepy browser extension? – Miguel Valencia Apr 24 '20 at 04:55
  • @MiguelValencia: the site doesn't seem to exist anymore, I have removed the link – Sascha Galley Apr 24 '20 at 16:08
  • Thank you for your clear & simple answer. Modernizer now recommends against using navigator.cookieenabled: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cookies.js – joshterrell805 Jul 24 '20 at 21:24
  • Note: When the browser is configured to block third-party cookies, and navigator.cookieEnabled is invoked inside a third-party iframe, it returns true in Safari, Edge Spartan and IE (while trying to set a cookie in such scenario would fail). It returns false in Firefox and Chromium-based browsers. https://developer.mozilla.org/en-US/docs/Web/API/Navigator/cookieEnabled – csandreas1 May 06 '21 at 16:55
17

But to check whether cookies are enabled using isset($_COOKIE["cookie"]) you have to refresh. Im doing it ths way (with sessions based on cookies :)

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

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

if ($a == $b)
    echo"Cookies ON";
else
    echo"Cookies OFF";
misza
  • 219
  • 2
  • 2
  • 2
    This is the most simple and best example so far! One comment: First check if the session is already started before you do this and keep it enabled when you finishing the test. – Codebeat Feb 08 '13 at 22:36
  • See my modified and more robust post of your answer on this page! – Codebeat Apr 04 '13 at 12:37
  • 11
    This only works after refresh! On the first load it always says _Cookies OFF_ because there is _no way_ to test if cookies are enabled without exchanging at least one request with the browser. Cookies come as a part of header information with every request and cookie manipulations are done with response headers. There's no way around it. – Pavel Feb 05 '14 at 13:38
11

Answer on an old question, this new post is posted on April the 4th 2013

To complete the answer of @misza, here a advanced method to check if cookies are enabled without page reloading. The problem with @misza is that it not always work when the php ini setting session.use_cookies is not true. Also the solution does not check if a session is already started.

I made this function and test it many times with in different situations and does the job very well.

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

Usage:

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

Important note: The function temporarily modify the ini setting of PHP when it not has the correct setting and restore it when it was not enabled. This is only to test if cookies are enabled. It can get go wrong when you start a session and the php ini setting session.use_cookies has an incorrect value. To be sure that the session is working correctly, check and/or set it before start a session, for example:

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

     }
    else { echo 'Cookies are NOT enabled!'; }
Codebeat
  • 6,501
  • 6
  • 57
  • 99
  • Erwinus, can you please explain a bit more what you mean by saying "It can get go wrong when you start a session and the php ini setting session.use_cookies has an incorrect value". What value could be incorrect? I am trying to implement your idea but was not sure what I need to set my php ini to... Thank you! – Sebastian Jun 09 '13 at 17:07
  • 2
    @Sebastian: When you have started a session BEFORE you going to check if cookies are enabled AND session.use_cookies is FALSE for example, it might fail. To be sure that is working correctly you have to call first the testfunction suGetClientCookiesEnabled() BEFORE starting any session. Is this clear/understandable for/to you? Hopes it helps. – Codebeat Jun 10 '13 at 16:14
  • Unfortunately it doesn't work the first time a site is called, e.g. try in incognito mode. *After* the first call to a site, you can expect $_COOKIE['PHPSESSID'] to be set and that proves cookies are enabled, but on the very first call it is empty - with your method you still get a new session id every time, it doesn't prove anything. – Rob Nov 13 '14 at 10:18
  • @Rob: I think you do something wrong. You must check cookies are enabled BEFORE you start any other session. See also comment to Sebastian and the 'important note' in the answer. For security reasons it is better to rename the session name: ini_set( 'session.name', 'your name' ) and ini_set( 'session.use_only_cookies', true ); and ini_set( 'session.use_trans_sid', false ); – Codebeat Nov 13 '14 at 22:41
  • 3
    @Erwinus - you didn't try it? To prove what I said, please try: 1. Create a php file with the code from your answer in it 2. Open a new *incognito window* in chrome 3. Browse directly to the php test file. First call says: "Cookies are NOT enabled!". Second call says: "Cookies are enabled!". I was merely pointing this out. Unfortunately it makes your code a little bit of a waste of time, because on the 2nd call, you can check if $_COOKIE['PHPSESSID'] is populated - if it is, then cookies are enabled. – Rob Jan 21 '15 at 15:36
9

A transparent, clean and simple approach, checking cookies availability with PHP and taking advantage of AJAX transparent redirection, hence not triggering a page reload. It doesn't require sessions either.

Client-side code (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 call can be replaced with pure JavaScript AJAX call)

Server-side code (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();
    }
}

First time the script is called, the cookie is set and the script tells the browser to redirect to itself. The browser does it transparently. No page reload takes place because it's done within an AJAX call scope.

The second time, when called by redirection, if the cookie is received, the script responds an HTTP 200 (with string "true"), hence the showCookiesMessage function is called.

If the script is called for the second time (identified by the "reload" parameter) and the cookie is not received, it responds an HTTP 200 with string "false" -and the showCookiesMessage function gets called.

zibilico
  • 91
  • 1
  • 3
  • 1
    This approach will work on most devices, but will go crazy if javascript is disabled – ppp Feb 13 '14 at 23:36
6

You cannot in the same page's loading set and check if cookies is set you must perform reload page:

  • PHP run at Server;
  • cookies at client.
  • cookies sent to server only during loading of a page.
  • Just created cookies have not been sent to server yet and will be sent only at next load of the page.
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
drfunjohn
  • 69
  • 1
  • 1
  • It is possible, see my answer – Codebeat Apr 04 '13 at 19:43
  • Thanks Martijn. I just learning and appreciate that conformation. I find the whole idea of being able to set or read cookies in a PHP script very confusing, because of your very first point. To go by the PHP manual, you'd think that as long as you do a setcookie() prior to your tag, it would be there for you to immediately read a line of code later, which seems pretty much impossible to me unless I'm missing something major. Frankly, the mechanism by which your last point occurs is still a mystery to me. I wish I could find a definitive explanation of how this works. – Randy Aug 09 '15 at 00:15
2

You can make an Ajax Call (Note: This solution requires 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';
}

As result an alert box appears which shows wheter cookies are enabled or not. Of course you don't have to show an alert box, from here you can take other steps to deal with deactivated cookies.

Black
  • 18,150
  • 39
  • 158
  • 271
1

JavaScript

You could create a cookie using JavaScript and check if it exists:

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

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

Or you could use a jQuery Cookie plugin

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

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

Php

setcookie("testcookie", "testvalue");

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

}

Not sure if the Php will work as I'm unable to test it.

Tomgrohl
  • 1,767
  • 10
  • 16
  • 2
    The PHP code won't work. You need to reload the page so that the browser sends a second HTTP request. If the second HTTP request has the cookie that was set from the first HTTP request, then cookies are enabled. – Dave Jarvis Sep 25 '12 at 18:09
0

Here is a very useful and lightweight javascript plugin to accomplish this: 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);

Works in all browsers, accepts any character.

Grant
  • 2,413
  • 2
  • 30
  • 41
0

Cookies are Client-side and cannot be tested properly using PHP. That's the baseline and every solution is a wrap-around for this problem.

Meaning if you are looking a solution for your cookie problem, you are on the wrong way. Don'y use PHP, use a client language like Javascript.

Can you use cookies using PHP? Yes, but you have to reload to make the settings to PHP 'visible'.

For instance: Is a test possible to see if the browser can set Cookies with plain PHP'. The only correct answer is 'NO'.

Can you read an already set Cookie: 'YES' use the predefined $_COOKIE (A copy of the settings before you started PHP-App).

Harm
  • 787
  • 7
  • 11
0

it is easy to detect whether the cookies is enabled:

  1. set a cookie.
  2. get the cookie

if you can get the cookie you set, the cookie is enabled, otherwise not.

BTW: it is a bad idea to Embedding the session id in the links and forms, it is bad for SEO. In my opinion, it is not very common that people dont want to enable cookies.

James.Xu
  • 8,249
  • 5
  • 25
  • 36
  • 1
    FYI, you would actually be surprised. I have a Firefox plugin that blocks all cookies except domains on a whitelist, and have noticed many users following suit. In fact, that is what prompted the question: I couldn't use the form and couldn't figure out why at first, lol. – steveo225 Jul 12 '11 at 12:24
  • what do you mean by can not use the form? can not embed the jsessionid into form? – James.Xu Jul 12 '11 at 12:35
  • The form is a multi-submit system, without cookies enabled, the page kept starting over instead of continuing because the session could never be set. – steveo225 Jul 12 '11 at 12:40
  • In Europe there is a new cookielaw that afraid allot of people to enable cookies because a website must ask to accept cookies. This question irritates visitors allot, because of this they turn off cookies completely. You said: "not very common", that is true because they did not know it was there. Because of this stupid law more people know about it and turn it off when they know how to do that. – Codebeat Feb 08 '13 at 22:43