Datenaustausch zwischen Dokumenten

In JavaScript existieren keine über Dokumentgrenze hinweg gültigen globalen Variablen. Damit sind aus Sicht eines JavaScript Programms Dokumente unabhängige Objekte und somit ist der Datenaustausch zwischen verschiedenen Dokumenten nicht direkt möglich.

Eine Lösung wäre, Daten auszutauschen, indem man die Werte über den Web-Server an andere Dokumente "sendet". Dies ist ein Weg, bei dem serverseitig Programme (z.B.CGI-Skripte) zu realisieren sind.

Im Folgenden werden zwei Techniken vorgestellt, mit denen man ohne über den Web-Server zu gehen, Daten zwischen Dokumenten austauschen kann. Danach wird kurz auf die Möglichkeit der CGI Programme eingegangen.

Kommandozeilenparameter

Bestandteil einer WWW-Adresse ist u.a. der "Search String" (vgl. Internetadresse). Dieser wird normal verwendet, um Daten zum Web-Server zu senden, der dies durch Programme auswertet. Die im Search-String enthaltenen Daten kann man durch JavaScript Programme lesen und schreiben.

Im folgenden Beispiel wird von dem Dokument "from.htm" das Dokument "to.htm" geladen, wobei die in "from.htm" eingegebenen Daten in "to.htm" angezeigt werden.

from.htm:

<html>
<head>
<title>from</title>
<script language="JavaScript">
function seiteLaden(uebergabe) {
    location.href =     "http://www.fbi.h-da.de/~a.schuette/Vorlesungen/JavaScript/
                           Datenaustausch/to.htm?" +  escape(uebergabe);
}
</script>
</head>
<body>
Der eingegebene Text wird auf einer anderen Seite angezeigt.<br>
<form>
    <textarea name="eingabe" rows="5" cols="20">
    </textarea> <br>
    <input type="button" value="Seite Laden"
        onClick="seiteLaden(this.form.eingabe.value)">
</form>
</body>
</html>

to.htm:

<html>
<head>
<title>to</title>
<script language="JavaScript">
function uebergabeHolen() {
    var uebergabe = location.search;
    alert(uebergabe);
    uebergabe = uebergabe.substring(1,uebergabe.length);
    document.fo.ausgabe.value = unescape(uebergabe);
}
</script>
</head>
<body onLoad="uebergabeHolen()">
Dieser Text wurde auf der letzten Seite eingegeben.<br>
<form name="fo">
    <textarea name="ausgabe" rows="5" cols="20">
    </textarea> <br>
</form>
</body>
</html>

Das Fragezeichen "?" in "search" wird durch die Funktion "substring()" entfernt und durch "unescape()" wird die Ausgabe lesbar gemacht.

Cookies

JavaScript hat nur eingeschränkte Möglichkeiten (aus Sicherheitsgründen), um auf Dateien des Client-Rechners zuzugreifen.  Cookies sind kleine Dateien mit vorgegebenem Format, die auf einem Client abgelegt sind und von WWW Seiten erzeugt werden. Cookies wurden eingeführt, um Daten auf einem Client speichern zu können, wenn von einem Server eine HTML Datei angefordert wird. Somit kann der Server bei erneutem Request erkennen, dass die Seite schon vorher angefordert wurde.

Cookies sind für unterschiedliche Anwendungsgebiete verwendbar, etwa, um

Mit JavaScript können Cookies erzeugt und gelesen werden.

Ein Cookie besteht in der einfachsten Form aus einem Namen und einem Wert. Der Name identifiziert das Cookie. Pro Server können nur eine gewisse Anzahl Cookies auf dem Client abgespeichert werden. 

Um ein Cookie zu erzeugen, kann man in JavaScript durch

    document.cookie = "TestCookie"

ein Cookie mit Namen "TestCookie" für den Server anlegen. Das Auslesen von Cookies ist etwas schwieriger - man kann nicht auf ein einzelnes Cookie zugreifen. Durch

    document.cookie

hat man Zugriff auf alle Cookies für den Server. Zur Verwaltung von Cookies sollte man deshalb Funktionen zum Erzeugen, Löschen und Lesen zu realisieren. Dies wird nun am Beispiel einer Seite, mit der man sich die Hintergrundfarbe über verschiedene Aufrufe hinweg merken kann, verdeutlicht.

Ausführen der Beispielseite!

Die allgemeine Form eines Cookie ist eine durch Semikolon separierte Folge, bestehend aus Paaren (Name=Wert) für

Eine Funktion, um die Hintergrundfarbe vom Benutzer zu erfragen und ein Cookie zu setzen ist:

function set(){
    favColor = prompt("What is your favorite background color?");
    SetCookie ('color', favColor, exp);
}

Nun die Funktion zum Setzen eines Cookie "SetCookie ":

function SetCookie (name, value) {
    var argv = SetCookie.arguments;
    var argc = SetCookie.arguments.length;
    var expires = (argc > 2) ? argv[2] : null;
    var path = (argc > 3) ? argv[3] : null;
    var domain = (argc > 4) ? argv[4] : null;
    var secure = (argc > 5) ? argv[5] : false;
    document.cookie = name + "=" + escape (value) +
        ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
        ((path == null) ? "" : ("; path=" + path)) +
        ((domain == null) ? "" : ("; domain=" + domain)) +
        ((secure == true) ? "; secure" : "");
}

Die Funktion setzt ein Cookie mit Namen "name" und Wert "value". Die Funktion ist ein Beispiel für Funktionen mit variabler Anzahl von Argumente. Die Argumente sind durch die Eigenschaft der Funktion "arguments", ein Array mit den Argumenten, definiert.

Das Argumentarray hat im o.a. Beispiel ist wie folgt aufgebaut::

Argument Bedeutung
0 = name Name des Cookie
1 = value Wert des Cookie, hier der Name der Hintergrundfarbe
2 Haltbarkeitsdatum
3 path
4 domain
5 secure

Das Haltbarkeitsdatum drück aus, bis wann auf das Cookie zugegriffen werden kann. Ein Zugriff nach dem Haltbarkeitsdatum ist nicht möglich. Wenn das Datum nicht gesetzt wird, so ist der Zugriff nur möglich, bis der Browser geschlossen wird.

Ein Cookie ist per Default nur in dem Verzeichnis gültig, in dem es erstellt wurde. D.h. nur von HTML Seiten, die im selben Verzeichnis sind, wie die Seite, die das Cookie erzeugt haben, kann auf das Cookie zugegriffen werden. Durch den 4. Parameter "path" kann man angeben, dass von allen Verzeichnissen, die unterhalb des Pfades stehen, zugegriffen werden kann..

Cookies können prinzipiell nur von dem Server aus gelesen werden, der für das Schreiben verantwortlich war.  So kann ein Cookie, das von "www.fbi.h-da.de" geschrieben wurde, nicht von "www.h-da.de" gelesen werden. Durch Angabe des 5. Argumentes ("h-da.de" ) könnte man die erreichen.

Der letzte Parameter (secure=ture) gibt an, dass der Zugriff nur über sichere Verbindungen möglich ist.

Unser Cookie wird aus der HTML Seite gelesen, indem die Funktion "color()" die Funktion "getCookie()" aufruft:

var expDays = 30;
var exp = new Date();
exp.setTime(exp.getTime() + (expDays*24*60*60*1000));
function color(){
    var favColor = GetCookie('color');
    if (favColor == null) {
        favColor = prompt("What is your favorite background color?");
        SetCookie('color', favColor, exp);
    }
    document.bgColor=favColor;
    return favColor;
}
 

 

<BODY>

<SCRIPT>
    document.write('your favorite background color is : ' + color());
</SCRIPT><br>
<a href="JavaScript:set()">Change background color</a>

</BODY>
 

Der Zugriff auf unser Cookie erfolgt durch die Funktionen:

function getCookieVal (offset) {
    var endstr = document.cookie.indexOf (";", offset);
    if (endstr == -1)
        endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie (name) {
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg)
            return getCookieVal (j);
        i = document.cookie.indexOf(" ", i) + 1;
        if (i == 0) break;
    }
    return null;
}
 

Ein Cookie wird "gelöscht", in dem man es mit einem anderen überschreibt oder ein Haltbarkeitsdatum, das in der Vergangenheit liegt, verwendet.

Beschränkungen

Cookies werden (unter Unix) in der Datei "cookies" gespeichert. In Windows werden Cookie-Dateien im persönlichen Verzeichnis abgelegt. Cookies sind nicht beliebig erzeugbar. Sowohl für Anzahl als auch die Größe gibt es Beschränkungen, die aber von Browser zu Browser variieren.

Anhaltspunkte sind:

Größe eines Cookie <= 4KByte (=4096 Byte)
Anzahl Cookies pro Server <=20
Gesamtzahl Cookies <= 300

CGI Programme

CGI Skripten sind serverseitig ablaufende Programme, die von einer HTML Form auf Client Seite aus gestartet werden können. Dazu wird das Programm in der Form als Wert des Attributs "ACTION" angegeben.

<form method="POST"
    action="http://www.fbi.h-da.de/~a.schuette/cgi-bin/store"
    onSubmit="return true;">

Im o.a. Beispiel wird das Programm "store" aufgerufen.

Ein CGI Skript liest die Clientanfrage über seine Standardeingabe und antwortet dem Client über seine Standardausgaben.

Ein CGI Skript, das die Daten, die der Client sendet, in eine Datei speichert ist etwa als Unix Shell Skript wie folgt realisiert:

#!c:/cygwin/bin/bash
PATH=/usr/bin:/bin:.
prog=$0
echo # dieses echo ist notwendig!!!!!
# --- Umgebung auf Server -------------------------------------
LOGFILE=$prog.log
STOREFILE=$prog.txt

# --- Umgebung von Client -------------------------------------
echo >> $LOGFILE
echo Content-type: text/plain >> $LOGFILE
echo CGI/1.0 test script report: >> $LOGFILE
echo argc is $#. argv is "$*". >> $LOGFILE
echo SERVER_SOFTWARE = $SERVER_SOFTWARE >> $LOGFILE
echo SERVER_NAME = $SERVER_NAME >> $LOGFILE
echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE >> $LOGFILE
echo SERVER_PROTOCOL = $SERVER_PROTOCOL >> $LOGFILE
echo SERVER_PORT = $SERVER_PORT >> $LOGFILE
echo REQUEST_METHOD = $REQUEST_METHOD >> $LOGFILE
echo HTTP_ACCEPT = "$HTTP_ACCEPT" >> $LOGFILE
echo PATH_INFO = "$PATH_INFO" >> $LOGFILE
echo PATH_TRANSLATED = "$PATH_TRANSLATED" >> $LOGFILE
echo SCRIPT_NAME = "$SCRIPT_NAME" >> $LOGFILE
echo QUERY_STRING = "$QUERY_STRING" >> $LOGFILE
echo REMOTE_HOST = $REMOTE_HOST >> $LOGFILE
echo REMOTE_ADDR = $REMOTE_ADDR >> $LOGFILE
echo REMOTE_USER = $REMOTE_USER >> $LOGFILE
echo AUTH_TYPE = $AUTH_TYPE >> $LOGFILE
echo CONTENT_TYPE = $CONTENT_TYPE >> $LOGFILE
echo CONTENT_LENGTH = $CONTENT_LENGTH >> $LOGFILE
echo >> $LOGFILE
# --- Anfrage von Client speichern ---------------------------
/usr/bin/sed -e 's/eingabe=//' > $STOREFILE
# --- Sender einer Bestätigung -------------------------------
cat <<!
<HTML>
<HEAD><TITLE>Titel</TITLE>
</HEAD>
<BODY>
Die Informationen wurden <bold>gespeichert!</bold>
</BODY>
</HTML>
!
# --- Exit ---------------------------------------------------
exit 0

Damit kann man dann ein Formular mit Daten, die gespeichert werden sollen wie folgt realisieren:

<html>

<head>
<title>from</title>
</head>
<body>
store.htm:<br>
Der eingegebene Text wird zum Web Server gesendet und dort gespeichert..<br>
<form method="POST" action="http://www.fbi.h-da.de/~a.schuette/cgi-bin/store" onSubmit="return true;">
<textarea name="eingabe" rows="5" cols="20">
</textarea> <br>
<input type="submit" value="submit">
</form>

</body>

</html>
 

Speichern

Das Lesen der auf dem Server gespeicherten Daten kann durch das folgende Formular erreicht werden; hier wird ein CGI Skript "restore" verwendet, um die Datei auf dem Server zu lesen.

<html>

<head>
<title>from</title>
</head>
<body>
restore.htm:<br>
Der auf dem Web Server gespeicherte Text wird angezeigt.<br>
<form method="POST" action="http://www.fbi.h-da.de/~a.schuette/cgi-bin/restore" onSubmit="return true;">
<input type="submit" value="submit">
</form>
</body>

</html>
 

Lesen

(Besser wäre es, eine Funktion zu verwendet, die durch "unescape()" die Daten in lesbare Form bringt.)

Das entsprechende CGI Skript (restore) ist:

#!c:/cygwin/bin/bash
PATH=/usr/bin:/bin:.
prog=$0
echo # dieses echo ist notwendig!!!!!

# --- Umgebung auf Server -------------------------------------
LOGFILE=$prog.log
RESTOREFILE=store.txt

# --- Umgebung von Client -------------------------------------
echo >> $LOGFILE
echo Content-type: text/plain >> $LOGFILE
echo CGI/1.0 test script report: >> $LOGFILE

...

# --- Anfrage von Client -------------------------------------
cat >> $LOGFILE
# --- Sende abgespeicherte Datei ----------------------------
cat $RESTOREFILE
# --- Exit ---------------------------------------------------
exit 0