32.3 Mit Cookies arbeiten  
Wenn Sie nicht mit Frames arbeiten können oder wollen, besteht eine Alternative darin, auf Cookies zurückzugreifen.
Mit Cookies sind Sie etwas flexibler als mit Frames, da Sie mit Cookies das Problem mit dem Öffnen von Links in einem neuen Fenster einfach umgehen können.
Das Hauptproblem besteht darin, sich ein Muster zum Speichern der Cookies zu überlegen. In Kapitel 12 wurden zwei Funktionen entwickelt, die an dieser Stelle sehr nützlich sein können:
|
schreiben_collection() |
|
lesen_collection() |
Mit den beiden Funktionen (die in der Datei cookies.js liegen) können Sie ein assoziatives Array schreiben, das wiederum in einem Cookie abgespeichert werden kann. So benötigen Sie nur einen einzigen Cookie, um den kompletten Warenkorb zu behalten.
Als Namen beziehungsweise Schlüssel im assoziativen Array verwenden wir die Bestellnummern, als Wert die jeweiligen Anzahlen.
32.3.1 Warenkorb füllen  
Die Funktion zum Füllen des Warenkorbs ist um einiges kürzer als die Funktion aus dem vorigen Abschnitt. Es gibt nämlich ein paar Unterschiede, die im Folgenden erläutert werden:
|
Die Daten werden mit den beiden zuvor genannten Funktionen aus der Datei cookies.js in einem Cookie gespeichert. |
|
Die Frame-Abfragen sind nicht mehr nötig, ebenfalls muss nicht mehr direkt auf die Daten aus artikel.js zugegriffen werden. Das geschieht an anderer Stelle. |
Zunächst betrachten wir, wie man von einem Artikel eine bestimmte Stückzahl zusätzlich in den Warenkorb legt:
function warenkorb_hinzufuegen_cookies(nr, stueck) {
var anzahl = lesen_collection(nr);
anzahl = parseInt(anzahl); // in Integer umwandeln
if (isNaN(anzahl)) {
anzahl = 0;
}
anzahl += stueck;
schreiben_collection(nr, anzahl);
}
Aus dem Cookie wird die aktuelle Anzahl ausgelesen und in einen Integerwert umgewandelt. Dann wird die neue Anzahl hinzuaddiert und der Wert wieder zurückgeschrieben.
Ganz ähnlich ist die Funktion aufgebaut, die einem Element im Warenkorb eine ganz bestimmte Stückzahl zuweist:
function warenkorb_editieren_cookies(nr, stueck) {
schreiben_collection(nr, stueck);
}
Dank der Vorarbeiten in Kapitel 12 besteht die Funktion, die zuvor noch recht umfangreich war, aus nur noch einer Codezeile.
32.3.2 Artikel anzeigen  
Um alle Artikel anzuzeigen, werden wieder drei verschiedene Dateien erstellt:
|
eine Seite, auf der alle Kategorien angezeigt werden: katego-rien_cookies.html |
|
eine Seite, auf der alle Artikel innerhalb einer Kategorie angezeigt werden: artikel_gesamt_cookies.html |
|
eine Seite, auf der ein Artikel in aller Ausführlichkeit angezeigt wird: artikel_einzeln_cookies.html |
Der Hauptunterschied zu der zuvor entwickelten Lösung auf Frames-Basis ist, dass die Artikel und Kategorien auf der aktuellen Seite in JavaScript-Variablen zur Verfügung stehen, da die Datei artikel.js direkt eingebunden ist.
Ansonsten ist der Code sehr ähnlich. Die Kategorien werden aus den JavaScript-Variablen ausgelesen und in einer Schleife ausgegeben. Die Kategorienamen werden zudem mit der Datei artikel_gesamt_cookies. html verlinkt. Die Datei warenkorb.js muss wegen der in artikel.js verwendeten Konstruktorfunktionen ebenfalls eingebunden werden:
<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte wählen Sie eine Kategorie!
<ul>
<script type="text/javascript"><!--
for (var i=0; i<kategorie.length; i++) {
document.write("<li\>");
document.write("<a href=\"artikel_gesamt_cookies.html?");
document.write(escape(kategorie[i].name));
document.write("\"\>");
document.write(kategorie[i].name);
document.write("</a\></li\>");
}
//--></script>
</ul>
</p>
</body>
</html>
In der Datei artikel_gesamt_cookies.html werden alle Artikel aus einer Kategorie ausgegeben. Auch hier gibt es kaum einen Unterschied zur Datei artikel_gesamt_frames.html; lediglich der Zugriff auf die Daten aus artikel.js ändert sich, und die Frame-Referenz entfällt:
<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte wählen Sie einen Artikel!
<ul>
<script type="text/javascript"><!--
if (location.search.length > 1) {
var name = location.search.substring(1,
location.search.length);
name = unescape(name);
for (var i=0; i<kategorie.length; i++) {
if (kategorie[i].name == name) {
for (var j=0; j<kategorie[i].artikel.length; j++) {
var a = kategorie[i].artikel[j];
document.write("<li\>");
document.write("<a href=\
"artikel_einzeln_cookies.html?");
document.write(escape(a.nr));
document.write("\"\>");
document.write(a.name);
document.write("</a\></li\>");
}
}
}
}
//--></script>
</ul>
</p>
<p><a href="kategorien_cookies.html">Zurück zur
Übersicht</a></p>
<p><a href="warenkorb_cookies.html">Bestellung
aufgeben</a></p>
</body>
</html>
Auf der Seite artikel_einzeln_cookies.html muss dann der einzelne Artikel angezeigt werden und – auf Knopfdruck – zum Warenkorb hinzugefügt werden. Auch dazu verwenden wir wieder eine Hilfsfunktion namens hinzu(), die ein wenig anders aussieht als zuvor. Sie ahnen es bereits: Alle Frame-Referenzen sind verschwunden.
function hinzu(f, nr) {
if (f.elements["anzahl" + nr]) {
var anzahl = f.elements["anzahl" + nr].value;
anzahl = parseInt(anzahl); //Umwandlung in Int
if (isNaN(anzahl)) {
anzahl = 0;
}
warenkorb_hinzufuegen_cookies(nr, anzahl);
alert("Artikel hinzugefügt!");
}
}
 Hier klicken, um das Bild zu Vergrößern
Abbildung 32.6 Ein (mehr oder weniger) kryptischer Cookie repräsentiert den Warenkorb.
Der Rest der Seite sieht so wie oben aus, wenn man von Frame-Verweisen einmal absieht. Ebenso wird der (nicht mehr vorhandene) Übersichtsframe nicht mehr neu geladen, da diese Anweisung ins Leere führen würde:
<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
<script type="text/javascript" src="cookies.js"></script>
</head>
<body>
<h1>Willkommen im Online-Buch-Shop</h1>
<p>Bitte geben Sie die Stückzahl an!
<script type="text/javascript"><!--
function kategoriename(nr) {
for (var i=0; i<kategorie.length; i++) {
for (var j=0; j<kategorie[i].artikel.length; j++) {
if (kategorie[i].artikel[j].nr == nr) {
return kategorie[i].name;
}
}
}
return "";
}
function hinzu(f, nr) {
if (f.elements["anzahl" + nr]) {
var anzahl = f.elements["anzahl" + nr].value;
anzahl = parseInt(anzahl); //Umwandlung in Int
if (isNaN(anzahl)) {
anzahl = 0;
}
_warenkorb_hinzufuegen_cookies(nr, anzahl);
alert("Artikel hinzugefügt!");
}
}
document.write("<ul\>");
if (location.search.length > 1) {
var nr = location.search.substring(1,
location.search.length);
nr = unescape(nr);
var name = kategoriename(nr);
for (var i=0; i<kategorie.length; i++) {
if (kategorie[i].name == name) {
for (var j=0; j<kategorie[i].artikel.length; j++) {
if (kategorie[i].artikel[j].nr == nr) {
var a = kategorie[i].artikel[j];
document.write("<h2\>" + a.name + "</h2\>");
document.write("<b\>" + a.kurz + "</b\>");
document.write("<img src=\"" + a.grafik + "\"\>");
document.write("<br\>" + a.lang + "<br\>");
document.write("<form\>");
document.write("<input type=\"text\" ");
document.write("name=\"anzahl" + nr + "\" ");
document.write("size=\"2\" value=\"1\" /\> ");
document.write(name + " ");
document.write(a.preis + "€ "); // Preis in €
document.write("<input type=\"button\" value=\"In
den Warenkorb\" ");
document.write("onclick=\
"javascript:hinzu(this.form, '" +
nr + "')\" /\><br /\>");
document.write("</form\>");
}
}
}
}
document.write("</ul\><a href=\"artikel_gesamt_cookies.html?");
document.write(escape(name));
document.write("\"\>");
document.write("Zurück zu Kategorie " + name +"</a\>");
} else {
document.write("</ul\>");
}
//--></script>
</p>
<p><a href="warenkorb_cookies.html">Bestellung
aufgeben</a></p>
</body>
</html>
Mit relativ wenig Aufwand haben Sie die Artikelseiten des Frame-Warenkorbs in eine Lösung ohne Frames umgeschrieben, die auf Cookie-Basis arbeitet.
32.3.3 Warenkorb ändern  
Jetzt fehlt nur noch eine Datei: der Warenkorb. Dieser wird mit der zuvor erläuterten Taktik umgeschrieben:
|
Die Datei artikel.js wird eingebunden, ebenso die Dateien warenkorb.js und cookies.js. |
|
Alle Frame-Referenzen werden entfernt. |
Dass das Ganze so einfach funktioniert, liegt an der Routine zum Auslesen der Stückzahlen aus dem Cookie:
var anzahl = lesen_collection(nr);
anzahl = parseInt(anzahl); // in Integer umwandeln
if (isNaN(anzahl)) {
anzahl = 0;
}
Auch, wenn zu einem Artikel keine Daten in dem Cookie gespeichert sind, wird die korrekte Anzahl ermittelt, in diesem Fall 0.
Werfen wir noch einen Blick auf die Aufgabenverteilung: Wir müssen hier zweigleisig fahren:
|
Die Artikelnummern werden aus den Variablen in der Datei artikel.js ermittelt. |
|
Die zugehörigen Stückzahlen kommen aus dem Cookie bzw. der Cookie-Collection (mit kräftiger Mithilfe der Funktionen in der Datei cookies.js). |
Ansonsten sind keine weiteren Änderungen nötig. Aus diesem Grund finden Sie im Folgenden sofort das komplette Listing:
<html>
<head>
<title>Online-Shop</title>
<script type="text/javascript" src="warenkorb.js"></script>
<script type="text/javascript" src="artikel.js"></script>
<script type="text/javascript" src="cookies.js"></script>
</head>
<body>
<h1>Warenkorb</h1>
<form method="post" action="skript.php">
<script type="text/javascript"><!--
function update(f) {
for (var i=0; i<f.elements.length; i++) {
if (f.elements[i].type == "text" &&
f.elements[i].name.substring(0, 6) == "anzahl") {
var nr = f.elements[i].name.substring(6,
f.elements[i].name.length);
var anzahl = f.elements[i].value;
anzahl = parseInt(anzahl);
if (isNaN(anzahl)) {
anzahl = 0;
}
warenkorb_editieren_cookies(nr, anzahl);
}
}
location.reload();
}
document.write("<table border=\"1\" cellpadding=\"2\"\>");
var summe = 0;
for (var i=0; i<kategorie.length; i++) {
for (var j=0; j<kategorie[i].artikel.length; j++) {
var a = kategorie[i].artikel[j];
var anzahl = lesen_collection(a.nr);
if (anzahl>0) {
document.write("<tr\><td\>");
document.write("<input type=\"text\" ");
document.write("name=\"anzahl" + a.nr + "\" ");
document.write("size=\"2\" ");
document.write("value=\"" + anzahl + "\" /\> ");
document.write("</td\><td\>");
document.write("<i\>" + a.nr + "</i\> ");
document.write("</td\><td\>");
document.write("<b\>" + a.name + "</b\> ");
document.write("</td\><td\>");
document.write((anzahl * a.preis) + " € ");
document.write("</tr\>");
summe += anzahl * a.preis;
}
}
}
document.write("</table\>");
//--></script>
<br />
<input type="button" onclick="update(this.form)"
value="Aktualisieren" />
<input type="submit" value="Bestellung aufgeben" />
</form>
<a href="kategorien_cookies.html">Zurück zur
Übersicht</a></body>
</html>
Der Warenkorb funktioniert nun vollständig ohne Frames, aber mit Cookies. Sie müssen die Vor- und Nachteile hier sorgfältig abwägen. Auf jeden Fall sollten Sie überprüfen, ob der Browser des Benutzers Cookies unterstützt oder nicht. Das geht in zwei Schritten (natürlich wieder unter Verwendung von Features aus Kapitel 12). Zunächst benötigen Sie eine Funktion, die einen Cookie löscht, indem ein Ablaufdatum in der Vergangenheit gesetzt wird:
function cookie_loeschen() {
var anzParameter = cookie_loeschen.arguments.length;
var parameter = cookie_loeschen.arguments;
// 1. Cookie-Name
var name = parameter[0];
// 2. Domain
var domain = (anzParameter >= 2) ? parameter[1] : null;
// 3. Pfad
var path = (anzParameter >= 3) ? parameter[2] : null;
if (path != null) {
path = escape(path); // Sonderzeichen umwandeln
}
// 4. Sicherheitsstufe
var secure = (anzParameter >= 4) ? parameter[3] : null;
// Haltbarkeitsdatum
var expires = new Date(1977, 0, 1, 0, 0, 1);
// Aufruf von cookie_setzen
cookie_setzen(name, "", expires, domain, path, secure);
}
Damit lässt sich die Funktion cookie_support() erstellen. Sie setzt erst ein Cookie, prüft, ob es erfolgreich gesetzt werden konnte, und löscht es dann wieder.
function cookie_support() {
cookie_setzen("testcookie", "ok");
if (cookie_lesen("testcookie") == "ok") {
cookie_loeschen("testcookie");
return true;
} else {
return false;
}
}
Sie sollten dann auf der Hauptseite Ihres Angebots eine Abfrage nach folgendem Muster integrieren:
if (!cookie_support()) {
location.href = "keine-cookies.html";
}
Auf der Seite keine-cookies.html können Sie dann einen entsprechenden Hinweis anbringen und die Benutzer darauf hinweisen, dass sie die Cookie-Unterstützung ihrer Browser aktivieren müssen.
|