Use of Cookies on the Flood Warning Centre Web Pages

 

Background:

The Flood Warning Centre web pages use cookies to improve the display of the rainfall and river height data maps. The cookies allow for the users selection of data type and clickable/non clickable to be remembered when moving between maps of different areas and zooming in and out. They are temporary (Time To live is set to 3 hours) cookies and are not used to monitor user behaviour and have been implemented based on user feedback.
No server side cookie or cgi scripts are used and as all the processing is in the clients browser there are practically no security concerns with this cookie implementation.
If the user decides to disable cookies the displays will function as previously and use a default of displaying the 9am Rainfall on entry to all pages.

 

Cookie structure:

The cookie stores two items ...

  • A String representing the default data type being displayed ie. River, 24 Hour Rainfall, Since 9am Rainfall and Last hours rainfall. The abbreviated values stored are "river", "24hr", "since", and "last" respectively.
  • A Boolean which indicates if the user has selected the clickable version or not . The values are "Y" and "N".


The cookie also contains fixed fields of

  • A cookie name which in this case is BOM_HYDRO
  • A URL which in this case is www.bom.gov.au/hydro/flood.
  • A deletion period which is set to 3 hours.

 

Methodology:

The cookies are implemented using client side Javascript which is available by sourcing /hydro/flood/hyweb.js. On entering the site the Javascript function called “get_default” checks for the existence of a cookie named “BOM_HYDRO”, and if it exists, extracts the last used data display and Boolean indicating clickable or non clickable. If it does not find a cookie it sets these to the defaults of 24 Hour Rainfall and Non-clickable.
Javascript functions are used for zooming into another map and for switching the image on the current page. Within these routines, the cookie parameters are read, and the routine “switch_image” updates the cookie and sets the default data display to the current data type.
Every map based page checks for the existence of the cookie on display and uses the parameters if available.

 

Program Code

Source Code  
// ----------------------------------------------------------------------------
// Javascript functions used by the Commonwealth Bureau of Meteorology
// Flood Warning Centre Web Site
// Copyright BOM 2002
// ----------------------------------------------------------------------------


// ----------------------------------------------------------------------------
// Get the default parameters (This function is used in the clickable maps)

function get_default()
{
var cookieValue, pieces, dataset;

cookieValue=ReadCookie("BOM_HYDRO");
pieces=breakdown(cookieValue);
dataset = pieces[1];
defaultClickable = pieces[2];

if (dataset == "river") { defaultGif = riverGif; defaultData = riverData;}
if (dataset == "24hr") { defaultGif = dayGif; defaultData = dayData;}
if (dataset == "since") { defaultGif = sinceGif; defaultData = sinceData;}
if (dataset == "last") { defaultGif = lastGif; defaultData = lastData;}
if (dataset == "") { defaultGif = dayGif; defaultData = dayData;}

//alert("Dataset = " + dataset + "\nClickable = " + defaultClickable);

}

// ----------------------------------------------------------------------------
// Get the default parameters (Used in the top index.shtml and non-clickable maps)

function get_default_index()
{
var cookieValue, pieces, dataset;

cookieValue=ReadCookie("BOM_HYDRO");
pieces=breakdown(cookieValue);
dataset = pieces[1];
defaultClickable = pieces[2];

if (dataset == "river") { defaultGif = riverGif; defaultDataset = "river";}
if (dataset == "24hr") { defaultGif = dayGif; defaultDataset = "24hr";}
if (dataset == "since") { defaultGif = sinceGif; defaultDataset = "since";}
if (dataset == "last") { defaultGif = lastGif; defaultDataset = "last";}
if (dataset == "") {
defaultGif = dayGif; defaultDataset = "24hr"; defaultClickable = "N";
alert("If you have cookies enabled, this site will use \na cookie to remember the data type selection.")
}

//alert("Dataset = " + defaultDataset + "\nClickable = " + defaultClickable);

}

// ----------------------------------------------------------------------------
// Switches the image and the data set used for the popup

function switch_image_map(dataset)
{
var im_name,map_name;

if (dataset == "river") { im_name = riverGif; map_name = riverData;}
if (dataset == "24hr") { im_name = dayGif; map_name = dayData;}
if (dataset == "since") { im_name = sinceGif; map_name = sinceData;}
if (dataset == "last") { im_name = lastGif; map_name = lastData;}
if (dataset == "default") { im_name = defaultGif; map_name = defaultData;}

var now = new Date();
Image_update = new Image();
Image_update.src = im_name + '?' + now.getTime();
document.mapwindow.src = Image_update.src;
document.mapwindow.useMap = map_name;

// if changing the default then write cookie
// timeout is in milliseconds eg 3hrs x 60min x 60sec x 1000ms = 10800000

if (dataset != "default") {
value=combine(dataset,defaultClickable);
expiry=new Date((new Date()).getTime()+10800000);
WriteCookie("BOM_HYDRO",value, expiry);
}
}

// ----------------------------------------------------------------------------
// Update the cookie used in regional pages (clickabe and non clickable)

function update_cookie(dc)
{
var cookieValue, pieces, dataset;

cookieValue=ReadCookie("BOM_HYDRO");
pieces=breakdown(cookieValue);
dataset = pieces[1];

value=combine(dataset,dc);
expiry=new Date((new Date()).getTime()+10800000);
WriteCookie("BOM_HYDRO",value, expiry);

}

// ----------------------------------------------------------------------------
// Update the cookie used in index page

function update_cookie_index(ds,dc)
{

value=combine(ds,dc);
expiry=new Date((new Date()).getTime()+10800000);
WriteCookie("BOM_HYDRO",value, expiry);

}

// ----------------------------------------------------------------------------
// Display popup of river data

function RvMsg(name,value,fclass,tendency,obs_time)
{
var msgtext = "Name : " + name + "\nHeight : " + value + " m\nClass : " + fclass + "\nTendency : " + tendency + "\nObs Time : " + obs_time
confirm(msgtext)
}

// ----------------------------------------------------------------------------
// Display popup of rainfall data

function RnMsg(name,value,duration)
{
var msgtext = "Name : " + name + "\nRainfall : " + value + " mm\nDuration : " + duration + " hrs"
confirm(msgtext)
}


// ----------------------------------------------------------------------------
// Switch the map image on the top index.shtml document

function switch_image(dataset)
{
var im_name,map_name;

if (dataset == "river") { im_name = riverGif;}
if (dataset == "24hr") { im_name = dayGif;}
if (dataset == "since") { im_name = sinceGif;}
if (dataset == "last") { im_name = lastGif;}
if (dataset == "tend") { im_name = tendGif; dataset = "river";}
if (dataset == "default"){ im_name = defaultGif; dataset = defaultDataset;}

var now = new Date();
Image_update = new Image();
Image_update.src = im_name + '?' + now.getTime();
document.mapwindow.src = Image_update.src;

// Always write cookie

value=combine(dataset,defaultClickable);
expiry=new Date((new Date()).getTime()+10800000);
WriteCookie("BOM_HYDRO",value, expiry);
}

// ----------------------------------------------------------------------------
// Zoom into regional map

function zoom_in(indexfile)
{

var newURL;

if (defaultClickable == 'Y') {
newURL = indexfile + "_clickable.shtml";
} else {
newURL = indexfile + ".shtml";
}

//--If the selected file name is not blank, send it to reader.
if (newURL != "") {
//parent.display.location.href=newURL
location.href=newURL
}
}

// ----------------------------------------------------------------------------
// Combine fields into one cookie string

function combine(){

var delimiter, numArgs, combination, i;
combination="";
delimiter="|";
numArgs=combine.arguments.length;
if (numArgs>1) {
for (i=0; i<numArgs; i++) {
combination=combination+combine.arguments[i]+delimiter;
}
}
return combination.substring(0, combination.length-1);
}

// ----------------------------------------------------------------------------
// Break down cookie string into fields

function breakdown(combination){
var delimiter, start, end, count;
broken=new Object();
delimiter="|";
start=end=0;
count=1;
end=combination.indexOf(delimiter,end)
while ((end) && (end>-1)){
broken[count]=combination.substring(start,end);
count++;
start=end+1;
end=combination.indexOf(delimiter,start)
}
broken[count]=combination.substring(start,combination.length);
broken[0]=count+1;
return broken;
}

// ----------------------------------------------------------------------------
// Read cookie - get from browser

function ReadCookie(name){
var allCookie, CookieVal, length,start,end;
cookieVal="";
name=name+"="; //append equals to avoid false matches.
allCookie=document.cookie;
length=allCookie.length;
if (length>0) {//no cookies - user is probably incinerating cookies.
start=allCookie.indexOf(name,0)
if (start!=-1) {//if string appeared - otherwise cookie wasn't set.
start+=name.length;
end=allCookie.indexOf(";",start);
if (end==-1) {end=length;}
cookieVal=unescape(allCookie.substring(start,end));
}
}
return(cookieVal);
}

// ----------------------------------------------------------------------------
// Write cookie - send to browser

function WriteCookie(name,value,expires,domain,path,secure){
var CookieVal,CookError;
CookieVal=CookError="";
if (name) {
CookieVal=CookieVal+escape(name)+"=";
if (value) {
CookieVal=CookieVal+escape(value);
if (expires) {
CookieVal=CookieVal+"; expires="+expires.toGMTString();
}
if (domain){
CookieVal=CookieVal+"; domain="+domain;
}
if (path) {
CookieVal=CookieVal+"; path="+path;
}
if (secure) {
CookieVal=CookieVal+"; secure";
}
}
else {CookError=CookError+"Value failure";}//need valid value
}
else {CookError=CookError+"Name failure";}//need valid name
if (!CookError) {
document.cookie=CookieVal;//sets cookie
if (value != ReadCookie(name)) //checks to make sure it worked
{CookError="Write failure";}

}
return CookError;
}
// ----------------------------------------------------------------------------