JavaScript Editor JavaScript Validator     JavaScript Editor 



Team LiB
Previous Section Next Section

Cookie Security and IE6

IE6 has introduced a new security policy for cookies based on the P3P recommendations made by the World Wide Web Consortium, or W3C for short, a web standards body that deals with not only cookies but html, XML, and various other browser standards. Their website is at www.w3c.org and contains a host of information, though it's far from being an easy read. The general aim of P3P is to reassure users who are worried that cookies are being used to obtain personal information about their browsing habits. In IE 6 under the Tools ® Internet Options, select the Privacy tab to see where we can set the level of privacy with regards to cookies. (See Figure 11-16.) It's a balance between setting it so high that no website will work, or too low and run the risk of having your browsing habits recorded and potentially personal data stored:

Click To expand
Figure 11-16

Generally, by default session cookies are allowed, that is, cookies that last for only as long as the user is browsing our website. As soon as the user closes the browser, the session ends. However if we want cookies to outlast the user's visit to our website, we need to create a privacy policy in line with the P3P recommendations. This sounds a little complex, and certainly the fine details of the policy can be. However, IBM has created software that makes creating the XML for the policy fairly easy. It's not cheap, but there is a 90-day free trial. It can be downloaded from www.alphaworks.ibm.com/tech/p3peditor.

Plenty of other policy creation software is available; this just happens to be quite easy to use. P3PEdit is available for a much lower cost from http://policyeditor.com/.

Trivia Quiz – Storing Previous Quiz Results

Let's return to the trivia quiz and, using our knowledge of cookies, add the functionality to keep track of previous quiz results. We're going to calculate the user's average score for all the completed quizzes. We'll also allow the user to reset the statistics.

We need to alter only one page of the trivia quiz: the GlobalFunctions.htm page. First we need to add the two cookie functions, getCookieValue() and setCookie(), that we introduced earlier in the chapter. These can be added anywhere within the script block—I've added them after all the other functions.

function getCookieValue(cookieName)
{
   var cookieValue = document.cookie;
   var cookieStartsAt = cookieValue.indexOf(" " + cookieName + "=");
   if (cookieStartsAt == -1)
   {
      cookieStartsAt = cookieValue.indexOf(cookieName + "=");
   }
   if (cookieStartsAt == -1)
   {
      cookieValue = null;
   }
   else
   {
      cookieStartsAt = cookieValue.indexOf("=", cookieStartsAt) + 1;
      var cookieEndsAt = cookieValue.indexOf(";", cookieStartsAt);
      if (cookieEndsAt == -1)
      {
         cookieEndsAt = cookieValue.length;
      }
      cookieValue = unescape(cookieValue.substring(cookieStartsAt,
         cookieEndsAt));
   }
   return cookieValue;
}
function setCookie(cookieName, cookieValue, cookiePath, cookieExpires)
{
   cookieValue = escape(cookieValue);
   if (cookieExpires == "")
   {
      var nowDate = new Date();
      nowDate.setMonth(nowDate.getMonth() + 6);
      cookieExpires = nowDate.toGMTString();
   }
   if (cookiePath != "")
   {
      cookiePath = ";Path=" + cookiePath;
   }
   document.cookie = cookieName + "=" + cookieValue +
      ";expires=" + cookieExpires + cookiePath;
}

The final change we need is to the getQuestion() function. It's in this function that either a new question is written to the page or, if all the questions have been asked, that the final results are displayed. Currently we just write the number of questions that the user got right and rate the result. Now we're going to keep a running average of previous results and display this information as well. The addition is toward the end of the function, after the script that writes a rating to the page.

        default:
            questionhtml = questionhtml + "Excellent"
      }
      var previousNoCorrect = Math.floor(getCookieValue("previousNoCorrect"));
      var previousNoAsked = Math.floor(getCookieValue("previousNoAsked"));
      var currentAvgScore = Math.round(numberOfQuestionsCorrect /
         numberOfQuestionsAsked * 100);
      questionhtml = questionhtml + "<br>The percentage you've " +
         " answered correctly in this quiz is " + currentAvgScore + "%";
      if (previousNoAsked == 0)
      {
         previousNoCorrect = 0;
      }
    
      previousNoCorrect = previousNoCorrect + numberOfQuestionsCorrect;
      previousNoAsked = previousNoAsked + numberOfQuestionsAsked;
    
    
      currentAvgScore = Math.round(previousNoCorrect / previousNoAsked * 100);
      setCookie("previousNoAsked", previousNoAsked,"","");
      setCookie("previousNoCorrect", previousNoCorrect,"","");
      questionhtml = questionhtml + "<br>This brings your average todate to " +
         currentAvgScore + "%"
      questionhtml = questionhtml + "<p><input type=button " +
         "value='Reset Stats' " +
         "onclick=\"window.top.fraTopFrame.fraGlobalFunctions.setCookie" +
         "('previousNoAsked', 0,'','1 Jan 1970')\" " +
         "name=buttonReset>"
      questionhtml = questionhtml + "<p><input type=button " +
         "value='Restart Quiz' " +
         "onclick=\"window.location.replace('quizpage.htm')\" " +
         "name=buttonRestart>"
   }
   return questionhtml;
}

How It Works

So how does this new code work?

First we use cookies to retrieve the number of questions previously answered correctly and the number of questions previously asked in total.

      var previousNoCorrect = Math.floor(getCookieValue("previousNoCorrect"));
      var previousNoAsked = Math.floor(getCookieValue("previousNoAsked"));

Note that if no cookie is set then CookieValue() will return null, which Math.floor() converts to zero.

We then work out the average of the current score, which is simply the number of questions the user got correct in this quiz divided by the number the user answered and multiplied by 100.

      var currentAvgScore = Math.round(numberOfQuestionsCorrect /
         numberOfQuestionsAsked * 100);

We then add the average result to questionhtml, the string of html we'll be writing to the page.

      questionhtml = questionhtml + "<br>The percentage you've " +
         " answered correctly in this quiz is " + currentAvgScore + "%";

Next we check to see if the number of questions asked was previously zero. If it was, the user has reset the stats, or this is the first time that user has taken the quiz. We reset the number correct to zero, because it would hardly make sense if out of no questions answered our user got 10 right!

      if (previousNoAsked == 0)
      {
         previousNoCorrect = 0;
      }

Then we update the number of questions that the user previously answered correctly and the total number of previously answered questions, before using this information to calculate the running average of all the quizzes the user has taken since playing our quiz or resetting the stats.

      previousNoCorrect = previousNoCorrect + numberOfQuestionsCorrect;
      previousNoAsked = previousNoAsked + numberOfQuestionsAsked;
    
      currentAvgScore = Math.round(previousNoCorrect / previousNoAsked * 100);

We update our cookies with the new values in the next lines, using the setCookie() function we created earlier.

      setCookie("previousNoAsked", previousNoAsked,"","");
      setCookie("previousNoCorrect", previousNoCorrect,"","");

In the final new lines, we complete the construction of the results string, adding the running average and then creating two buttons. The first button will reset the number of questions asked by setting the previousNoAsked variable to zero, and the second is a replacement for the link that restarts the quiz.

      questionhtml = questionhtml + "<br>This brings your average todate to " +
         currentAvgScore + "%"
      questionhtml = questionhtml + "<p><input type=button " +
         "value='Reset Stats' " +
         "onclick=\"window.top.fraTopFrame.fraGlobalFunctions.setCookie" +
         "('previousNoAsked', 0,'','1 Jan 1970')\" " +
         "name=buttonReset>"
      questionhtml = questionhtml + "<p><input type=button " +
         "value='Restart Quiz' " +
         "onclick=\"window.location.replace('quizpage.htm')\" " +
         "name=buttonRestart>"

On the button creation lines, we need to include single quotes inside double quotes inside more double quotes. This will confuse JavaScript because it'll think the string has ended before it actually has. This is the reason that we use the special escape character \", which indicates that the double quotes are not delimiting a string, but part of the string itself.

Save the page and load TriviaQuiz.htm.

Now when you complete the quiz, you'll see a summary something like the one in Figure 11-17.

Click To expand
Figure 11-17

That completes the changes to the trivia quiz for this chapter.


Team LiB
Previous Section Next Section


JavaScript Editor JavaScript Validator     JavaScript Editor


©