Solved

Javascript multiple cookies do not work

Posted on 2009-04-09
6
1,084 Views
Last Modified: 2012-05-06
I have written a javascript to save cookies for customized settings for multiple users. When the HTML page is loaded, it prompts for a user name. Then it checks whether the user has associated cookie. If it does, then it retrieve that cookie string and load the user's settings from previous session.  

Lets say my HTML page has user John and Jessica. John is the first user and he saved the selections/settings when he left. The cookie string will be:

"John=ColorSel%3A1%3FLoadPage%3Ared_rose.html;"

If John revisted the page, the page will be loaded with his previous selections/settings. He can change it in the current session and the cookie string will be updated correctly. No issue here for a single user.

However, if Jesscia visits the HTML page. She looks and around and tries to save her selections/settings. Then for somehow the cookie string does not extend. I tried to assign the following new cookie string to doucument.cookie,

"John=ColorSel%3A1%3FLoadPage%3Ared_rose.html;
;Jessica=ColorSel%3A2%3FLoadPage%3Ayellow_rose.html"

But after assignment, when I print the document.cookie value, it only returns John's setting. So when Jesscia come back, the HTML load javascript could not find her cookie.

BTW, when I uploaded the HTML page to school website and launch it from there, it is stuck in the checkCookie() getUserName() function. The labtop vista task manager shows 50% CPU usage and finally the IE pop up an warning message saying that the page cause slow web response and should close.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 

  <head>

    <title>Assign2 bottom left frame</title>

    <script type="text/javascript"> <!--

      var g_username;

      var g_load_page;

      var g_is_new_cookie;

      

      /*

       * This function marks the current opened page in frame P3.

       */

      function markLoadPage( page_url )

      {

	    g_load_page = page_url;

      }

      

      /*

       * This function prompts user name when the page is re-loaded

       */       

	  function getUserName()

      {

	    do

	    {

          var username=prompt( 'Please enter your name:',"" );

        }       

        while( username == null || username =="" )

        

        return username;

      }
 

      /*

       * This is general function to get the cookie string for the specified cookie name

       */      

      function getCookie( c_name )

      {

        if( document.cookie.length>0 )

        {

          var c_start = document.cookie.indexOf( c_name + "=" );

          if( c_start!=-1 )

          { 

            c_start=c_start + c_name.length+1; 

            c_end=document.cookie.indexOf( ";",c_start );

            if( c_end==-1 ) c_end=document.cookie.length;

            return unescape( document.cookie.substring( c_start,c_end ));

          } 

        }

              

        return "";

      }
 

      /*

       * This function update the cookie. The cookie string contains the user 

       * preferenced selections on the HTML form.

       */      

      function setCookie()

      {	

	    var c_name = g_username;    

	    var c_value = "ColorSel:" + document.getElementById( "color_list" ).selectedIndex + "?" +

	                  "LoadPage:" + g_load_page;

	              	   

	    if( g_is_new_cookie )

	    {          

          tmp_cookie_str = document.cookie;

          if( document.cookie.length>0 )

          {

	        tmp_cookie_str = document.cookie;

	        

	        alert( "tmp_cookie_str = " + tmp_cookie_str );

	        

	        alert( "Assigned value =\n" +  tmp_cookie_str + ";" + c_name + "=" + escape( c_value ));

	        document.cookie = tmp_cookie_str + ";" + c_name + "=" + escape( c_value );

	        // document.cookie += ";" + c_name + "=" + escape( c_value );

          }

          else

          {

	        document.cookie = c_name + "=" + escape( c_value );

          }

        }

        else

        {

	      var newCookies = "";

	      var cookieArr = document.cookie.split( ";" );

	      

	      for( i=0; i<cookieArr.length; i++ )

	      {

		    var name_start = 0;

		    var name_end = cookieArr[ i ].indexOf( "=", 0 );

		    if( name_end == -1 )

		    {

			  alert( "Cookie String is corrupted at\n" + cookieArr[ i ] );

			  

			  continue;

		    }

		    

		    newCookies += ( newCookies.length > 0 )? ";" : "";

		    

		    var another_c_name = unescape( cookieArr[ i ].substring( 0, name_end ));

		    if( another_c_name == c_name )

		    {

			  newCookies += c_name + "=" + escape( c_value );

		    }

		    else

		    {

			  newCookies += cookieArr[ i ];

		    }

		  } // end of for    
 

	      

	      alert( "newCookies ==>\n" + newCookies );

	      

	      document.cookie = newCookies;

        }

        

        alert( "Saved cookies ==>\n" + document.cookie );    

      }
 

      /*

       * This function restores the user saved preference settings as the initial input

       * value to the HTML form fields.

       */      

      function restorePreference( cookieStr )

      { 

	    var fldArr = cookieStr.split( "?" );

	    

        for ( i=0; i<fldArr.length; i++) 

        {

          fldPair = fldArr[ i ];

          var broken_info = fldPair.split(":");

          var fld_name = broken_info[ 0 ];

          var fld_value = broken_info[ 1 ];

          

          switch( fld_name )

          {

	        case "ColorSel":

	        {

	          var idx = parseInt( fld_value );

	          document.getElementById( "color_list" ).selectedIndex = idx;

	          if( idx > 0 )

	          {

	            document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;

              }

            }

            case "LoadPage":

            {

	          parent.P3.location.href = fld_value;

            }

          } // end of switch

        }

      }
 

      /*

       * This function check the existing cookie for the user of previous session. It assums that there is

       * one and only one user for this HTML form. In another word, second user preference settings will 

       * overwrite the one of first user.

       */   

      function checkCookie()

      { 

	    g_username = getUserName();

	    

	    var cookieStr = getCookie( g_username );

	    

	    if( cookieStr!=null && cookieStr!="" )

        {

            restorePreference( unescape( cookieStr )); 

            g_is_new_cookie = false;

        }

        else

        {

          g_is_new_cookie = true;

        }

      }

      

      /*

       * This function set the background color of the P2 page

       */

  	  function setColor()

  	  {

	    var idx = document.getElementById( "color_list" ).selectedIndex;

	    if( idx > 0 )

	    {

	      document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;

        }

      }

//--></script>

  <style type="text/css"> <!--

    dl

    {

	  font-size:       medium;

	  test-decoration: underline;

	  margin-bottom:   0px;

	  padding:         0px;

    }

    select

    {

	  width:    5cm;

	  hight:    1cm;

    }

    table

    {

	  border:           1px;

	  border-spacing:   1px;

	  caption-side:     bottom;

	  border-collapse:  separate;

	  table-layout:     auto;

	  width:			100%;

	  empty-cells:		show;

    }

    option

    {

	  font-weight:  700;

    }

    .bt-style

    {

      border-color: efefef; 

      color: black; 

      font-family: arial, verdana, ms sans serif; 

      font-weight: bold; 

      font-size: 	 10pt; 

      width: 		 100px;

      height:		 25px

    }	  

//--></style>

  </head>

  <body onload="checkCookie()">

   <h2>Categories</h2>

   <dl><dt><a href="red_rose.html" target="P3" onclick="markLoadPage( 'red_rose.html' )">Red rose</a></dt></dl>

   <dl><dt><a href="pink_rose.html" target="P3" onclick="markLoadPage( 'pink_rose.html' )">Pink rose</a></dt></dl>

   <dl><dt><a href="yellow_rose.html" target="P3" onclick="markLoadPage( 'yellow_rose.html' )">Yellow rose</a></dt></dl>

   <dl><dt><a href="white_rose.html" target="P3" onclick="markLoadPage( 'white_rose.html' )">White rose</a></dt></dl>

   <dl><dt><a href="orange_rose.html" target="P3" onclick="markLoadPage( 'orange_rose.html' )">Orange rose</a></dt></dl>

   <dl><dt><a href="lavender_rose.html" target="P3" onclick="markLoadPage( 'lavender_rose.html' )">Lavender rose</a></dt></dl>

   <br/><br/><br/><br/>

   <form action="">

     <select name="color_list" id="color_list" onchange="setColor()">

       <option value="prompt">Choose a colour</option>

       <option value="red">red</option>

       <option value="pink">pink</option>

       <option value="yellow">yellow</option>

       <option value="white">white</option>

       <option value="orange">orange</option>

       <option value="lavender">lavender</option>

     </select>

     <br/><br/>

     <input type="button" class="bt_style" value="Save Selection" name="b_save" onclick="setCookie()" />

   </form>

  </body>

</html>

Open in new window

0
Comment
Question by:gs_kanata
  • 3
  • 2
6 Comments
 
LVL 10

Assisted Solution

by:webwyzsystems
webwyzsystems earned 100 total points
ID: 24108933
Your getUserName() function is a loop, rather than a "request and wait". Try the following to get rid of the huge CPU usage:

function getUserName(){
        var username=prompt( 'Please enter your name:',"" );    
        if( username == null || username =="" ){
                  // you could throw an alert in here to let user know why they are being prompted again.
                  getUserName();
         }
         else {
                  return username;
        }
}//end function

Rather than save your cookies as 'John=etc,etc,etc'....why not use an associative array?

prefs["John"]="johns info";
prefs["Jessica"]="jessica's info";

That way: prefs[username] will always resolve to the correct person's data.

You can use SERIALIZE to convert the array to a string to store in the cookie and UNSERIALIZE to restore it back to an array.
0
 

Author Comment

by:gs_kanata
ID: 24110568
Does the prompt( .. ) function act like request and wait? I am not sure as it behave like that in local machine if I enter the empty user name. However, if the HTML page is run in a web server, then the prompt simply not display. I really don't know what the local labtop CPU is busy with.

As for the cookie implementation, I appreciate and will try your suggestion. But that does not solve the issue to append more cookie to the document.cookie. For each windows login account, there is only one cookie file for one domain, right? And the cookie file has only one line having multiple cookies concatenated. The issue is that I can not append more cookie to that line. One it could, I have no issue to separate and extract properties and values.
0
 

Author Comment

by:gs_kanata
ID: 24110793
BTW, another strange thing the John's cookie string can be still retrieved even after I tried to delete all the cookies from control panel.

Attached are 2 screen capture files. One for Windows error message and another is the Control panel cookie deletion selection...
Alert.doc
delete-cookie.doc
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 

Author Comment

by:gs_kanata
ID: 24118945
I have figured out some issues:

(1) I have overkilled the multiple cookies. The javascript or the system has taken good care of it. So if one needs to update one cookie, then just write as
   
   document.cookie = c_name + "=" + c_value;

It won't overwrite the other cookie, only update the cooke has the same name if it exists. Otherwise, it just append a new cookie. So if it re-build the whole cookie line with multiple cookies separated with ";", then it will take the first one, as it can only update one cookie at a time.

(2) HTML webpage stuck duing the lauching from the remote website is because the security issue set in my IE. If I add that remote website as the truested site, then prompt will be display and stop there for user input.

However, back to cookie again, it saved cookie string seem can not survive from closing and starting the web page. Here is my testing step:

(1) Launch the HTML page, and enter a user name "user1".
(2) Navigate through pages and save the selection.
(3) Refresh the HTML main frame, and enter another user name say "user2".
(4) Repeat step 2 to save the customized selection
(5) Refresh the HTML main frame, and enter the first user name "user1". The user1's settings will be restored.
(6) Refresh the HTML main frame, and enter the second user name "user2". The user2's settings will be restored.

Everything seems to be fine so far until the HTML page is closed. Then when re-opening, the cookie string becomes empty and no user customized preference is restored.

Attached is the updated code




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 

  <head>

    <title>Assign2 bottom left frame</title>

    <script type="text/javascript"> <!--

      var g_username;
 
 

      /*

       * This function prompts user name for first load. So it assumes that only one

       * user uses this form

       */       

	  function getUserName()

      {

	    do

	    {

          var username=prompt( 'Please enter your name:',"" );

        }       

        while( username == null || username =="" )

        

        return username;

      }
 

      /*

       * This is general function to get the cookie string for the specified cookie name

       */      

      function getCookie( c_name )

      {

	    alert( "Retrieved cookies ==>\n" + document.cookie ); 

	    

        if( document.cookie.length>0 )

        {

          var c_start = document.cookie.indexOf( c_name + "=" );

          if( c_start!=-1 )

          { 

            c_start=c_start + c_name.length+1; 

            c_end=document.cookie.indexOf( ";",c_start );

            if( c_end==-1 ) c_end=document.cookie.length;

            return unescape( document.cookie.substring( c_start,c_end ));

          } 

        }

              

        return "";

      }
 

      /*

       * This function sets the cookie for the current exclusive user. The cookie string

       * contains the user preferenced selections on the HTML form.

       */      

      function setCookie()

      {	

	    var c_name = g_username;    

	    var c_value = "ColorSel&" + document.bgColor + "?" + "LoadPage&" + parent.P3.location.href;

	    

	    document.cookie = c_name + "=" + escape( c_value );
 

        alert( "Saved cookies ==>\n" + document.cookie );    

      }
 

      /*

       * This function restores the user saved preference settings as the initial input

       * value to the HTML form fields.

       */      

      function restorePreference( cookieStr )

      { 

	    var fldArr = cookieStr.split( "?" );

	    

        for ( i=0; i<fldArr.length; i++) 

        {

          fldPair = fldArr[ i ];

          var broken_info = fldPair.split("&");

          var fld_name = broken_info[ 0 ];

          var fld_value = broken_info[ 1 ];

          

          switch( fld_name )

          {

	        case "ColorSel":

	        {

		      document.bgColor = fld_value;
 

              break;

            }

            case "LoadPage":

            {	          

	          if( fld_value != "undefined" )

	          {

	            parent.P3.location.href = fld_value;

              }

              break;

            }

            default:

            {

	          alert( "Internal error: unsupported property name <" + fld_name + ">" );

            }

          } // end of switch

        }

      }
 

      /*

       * This function check the existing cookie for the user of previous session. It assums that there is

       * one and only one user for this HTML form. In another word, second user preference settings will 

       * overwrite the one of first user.

       */   

      function checkCookie()

      { 

	    g_username = getUserName();

	    

	    var cookieStr = getCookie( g_username );

	    

	    if( cookieStr!=null && cookieStr!="" )

        {

            restorePreference( unescape( cookieStr )); 

        }

      }

      

  	  function setColor()

  	  {

	    var idx = document.getElementById( "color_list" ).selectedIndex;

	    if( idx > 0 )

	    {

	      document.bgColor = document.getElementById( "color_list" ).options[ idx ].value;

        }

      }

//--></script>

  <style type="text/css"> <!--

    dl

    {

	  font-size:       medium;

	  test-decoration: underline;

	  margin-bottom:   0px;

	  padding:         0px;

    }

    select

    {

	  width:    5cm;

	  hight:    1cm;

    }

    table

    {

	  border:           1px;

	  border-spacing:   1px;

	  caption-side:     bottom;

	  border-collapse:  separate;

	  table-layout:     auto;

	  width:			100%;

	  empty-cells:		show;

    }

    option

    {

	  font-weight:  700;

    }

    .td_1

    {

	  font-style:  italic; 

	  font-size:   small;

	  font-weight: 700;

    }

    .td_2

    {

	  font-style:  italic; 

	  height:	   1cm;

    }

    .bt-style

    {

      border-color: efefef; 

      color: black; 

      font-family: arial, verdana, ms sans serif; 

      font-weight: bold; 

      font-size: 	 10pt; 

      width: 		 100px;

      height:		 25px

    }	  

//--></style>

  </head>

  <body onload="checkCookie()">

   <h2>Categories</h2>

   <dl><dt><a href="red_rose.html" target="P3">Red rose</a></dt></dl>

   <dl><dt><a href="pink_rose.html" target="P3">Pink rose</a></dt></dl>

   <dl><dt><a href="yellow_rose.html" target="P3">Yellow rose</a></dt></dl>

   <dl><dt><a href="white_rose.html" target="P3">White rose</a></dt></dl>

   <dl><dt><a href="orange_rose.html" target="P3">Orange rose</a></dt></dl>

   <dl><dt><a href="lavender_rose.html" target="P3">Lavender rose</a></dt></dl>

   <br/><br/><br/><br/>

   <form action="">

     <select name="color_list" id="color_list" onchange="setColor()">

       <option value="prompt">Choose a colour</option>

       <option value="red">red</option>

       <option value="pink">pink</option>

       <option value="yellow">yellow</option>

       <option value="white">white</option>

       <option value="orange">orange</option>

       <option value="lavender">lavender</option>

     </select>

     <br/><br/>

     <input type="button" class="bt_style" value="Save Selection" name="b_save" onclick="setCookie()" />

   </form>

  </body>

</html>

Open in new window

0
 
LVL 54

Accepted Solution

by:
b0lsc0tt earned 400 total points
ID: 24122593
gs_kanata,

The cookie doesn't have an expiration date so is "destroyed" when the browser closes.  In you setCookie() function you need to have it set an expiry date.  See snippet for an example.

Let me know if you have any questions or need more information.

b0lsc0tt
      function setCookie()
      {
          var days = 365; // number of days to save cookie, you set this value
          var dt = new Date();
          dt.setTime(dt.getTime() + (days*1000*60*60*24));
          var c_name = g_username;    
          var c_value = "ColorSel&" + document.bgColor + "?" + "LoadPage&" + parent.P3.location.href;
          
          document.cookie = c_name + "=" + escape( c_value ) + "; expires=" + dt.toGMTString();
 
        alert( "Saved cookies ==>\n" + document.cookie );    
      }

Open in new window

0
 
LVL 54

Expert Comment

by:b0lsc0tt
ID: 24131053
I'm glad I could help.  Thanks for the grade, the points and the fun question.
bol
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

This article discusses how to create an extensible mechanism for linked drop downs.
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
In this tutorial viewers will learn how to position overlapping items using z-index in CSS. They will also learn the restrictions on the z-index property.  Create a new HTML document with an internal stylesheet.: Create a div in CSS and name it Red.…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now