Microsoft arbeitet beständig daran, dass Windows mit jedem Update sicherer wird. Security Essentials ist die mitgelieferte Antivirensoftware, mit der das System frei von Malware gehalten werden soll. Allerdings erkennt diese viel zu wenige Bedrohungen und klaffende Sicherheitslücken werden von Viren, Mal- und Spyware sowie Phishing-Programmen gnadenlos ausgenutzt.
Aufgrund der Nutzung des modernen Webs reicht ein Neuaufspielen des Systems in vielen Fällen nicht mehr aus, um den Schaden einzudämmen. Passwörter, PIN-Nummern und persönliche Accounts sind bei Befall womöglich schon kompromittiert, der Schaden beläuft sich dann in vielen Fällen auf gesicherte Daten, Online-Accounts und bares Geld.
Und moderne Antivirensoftware muss Einiges leisten, um den Bedrohungen moderner Malware gewachsen zu sein: Beinahe 400.000 neue Viren werden jeden Tag registriert.
Hierzu erfüllt moderne Antivirensoftware gleich mehrere Funktionen. Die Firewall sichert das System gegen eingehende Bedrohungen ab und notiert seltsame Bewegungen von Datenpaketen auf den Rechner. Programme ohne Erlaubnis dürfen weder Daten senden noch empfangen. Auch ausgehende Daten werden von der Firewall blockiert, falls Spyware persönliche Dokumente und Daten ins Netz schicken möchte.
Der klassische Antivirenscanner durchforstet die Festplatte auf schädliche Software. Hierbei wird das System gründlich gescannt und auf alle in der Datenbank registrierten Viren abgeglichen. Wird ein Vorfall gefunden, werden entsprechend befallene Ordner und Programme unter Quarantäne gestellt und können anschließend gelöscht werden. Zu den namhaften (und in vielen Tests ausgezeichneten) Herstellern von Antivierensoftware für Windows zählen Bitdefender, Norton und Kaspersky. Diese drei Hersteller bieten einen umfassenden Schutz vor Zugriffen aus dem Netz und die Software wird stets aktualisiert, um sich immer neuen Bedrohungen anzupassen. Darüber hinaus gehören auch AVG, Avira und F-Secure sowie McAfee zu den Klassikern.
Ein alter Mythos zu Antivirensoftware gilt aber längst als entkräftet: Sie mache das System langsam. Prinzipiell benötigt jede App natürlich einen gewissen Anteil an Systemressourcen, auf Systemen mit Dual-Core-Prozessoren und einer zweistelligen Gigabyte-Zahl an Arbeitsspeicher sind die genutzten Ressourcen aber (in den meisten Fällen) entbehrlich.
Prinzipiell ist es immer sinnvoll, Antivirussoftware auf einem System zu installieren, ganz gleich ob Windows, Ubuntu oder Mac OS X. Aber Mac OS und Linux OS sind auf Grund ihrer Architektur deutlich sicherer als Windows, die Zahl der registrierten Viren ist deutlich geringer und die größte Sicherheitslücke beider Systeme ist der Adobe Flash Player. Nicht umsonst verzichten iOS und Android ganz auf Flash – Google in seinem Chrome Browser ab September ebenfalls.
Auf Linux-Systemen haben selbst viele Viren Schwierigkeiten, weil die Schadsoftware auf den unterschiedlichen Linuxdistributionen nicht läuft. Es ist schlicht nicht praktikabel, einen Virus zu entwickeln, der auf einem so geringen Prozentsatz von Rechnern läuft – vor allem wenn Linux die Schadsoftware Beschränkungen aussetzt. Denn wie auch unter Mac OS X laufen Apps und Plug-Ins in einer Sandbox und dürfen auf Systemdateien nicht zugreifen. Ein schwerwiegender Schaden wird so nahezu unmöglich gemacht und eine einfache Deinstallation bereinigt den Schaden.
Mac OS X geht sogar noch einen Schritt weiter und erlaubt in den Sicherheitseinstellungen – auch aus durchaus eigennützigen Gründen – nur die Installation von Apps aus dem Mac App Store. Zwar kann dies auf vertrauenswürdige Entwickler und alle Entwickler ausgeweitet werden, doch selbst dann greift das Sandbox-Prinzip.
Auf dem Mac kann sich Antivirensoftware vor allem deswegen lohnen, weil sie auch eine für Apple Devices harmlose Verbreitung von Malware für Windows aufspüren kann. Auch für Mac OS X gibt es Software-Suiten von Kaspersky, Bitdefender, Avira und Co. In der Arbeit behindern die Antivirenscanner nicht und schützen im Zweifelsfall andere Windows-Rechner im Netzwerk.
Ansonsten gilt es, auf allen Systemen stets die neuesten Updates zu installieren. Das gilt nicht nur für Apps, sondern vor allem auch für das Betriebssystem und vor allem für die stete Gefahrenquelle Flash. So kann die Gefahr des Virenbefalls bereits stark reduziert werden,
Auch umsichtiges Surfen gehört natürlich zum Schutz dazu, denn auch die beste Antivirensoftware stellt den User nicht von einem gewissen Maß an Eigenverantwortung frei. So sollte Software nur aus zuverlässigen Quellen installiert werden und Pop-up-Fenstern auf zwielichtigen Seiten sollten User grundsätzlich misstrauisch gegenüber stehen.
Regelmäßige Back-Ups gehören ebenfalls zum umfassenden Schutz gegen den Virenbefall, denn auch im Worst-Case-Szenario wird so dem Datenverlust vorgebeugt.
No related posts.
]]>
preg_match( "<link rel=\"openid.server\" href=\"(.*?)\" \/>", $quelle, $found );
$url = $found[1];
Falls Sie alle href Attribute von Links auslesen möchten:
preg_match_all( "<link rel=\"openid.server\" href=\"(.*?)\" \/>", $quelle, $found );
var_dump($found);
No related posts.
]]>In den vergangenen Tagen stand ich vor folgendem Problem. Ich hatte eine Menge an Photos über iTunes auf mein iPad überspielt. Leider musste der Laptop, auf dem ich die Bilder gespeichert hatte, in die Reparatur. Der Laptop kam mit einer leeren Festplatte zurück und ich hatte davor doch glatt vergessen, die Bilder sicherzustellen. Aber kein Problem – dachte ich – die Bilder sind ja gut aufgehoben auf dem iPad. Nichts da!
Eine Synchronisation der Bilder “zurück” funktioniert über iTunes leider nicht. Auch kann man nicht direkt auf die Bilder in den Alben zugreifen, wenn man das iPad an einen Windows PC anschließt. Man hat lediglich Zugriff auf die Bilder, die mit der iPad oder iPhone Kamera gemacht wurden.
Da war das Dilemma, wie komme ich an die Bilder? Es gibt natürlich eine kostenpflichtige app dazu, mit der das möglich gewesen wäre. Aber tut mir Leid, für eine solche einfache Kernfunktion zahle ich keinen Pfennig. In diesem Artikel möchte ich beschreiben, wie ich doch noch an alle Bilder gekommen bin – mit etwas PHP, einer kostenfreien app und ohne iTunes.
Damit alles funktioniert benötigen sie die kostenfreie app WiFi Photo Transfer auf ihrem iPad, zudem müssen sie in der Lage sein PHP Skripte auf ihrem Hauptrechner, also den Rechner auf den Sie die Bilder kopieren möchten, ausführen zu können. Wenn das möglich ist, dann ist die Arbeit wirklich ein Kinderspiel.
Installation der app “WiFi Photo Transfer”
Diese einfache app erlaubt es Ihnen, ihre Bilder auf dem iPad über einen URL zu erreichen und durch diese Bilder zu browsen. Damit könnten sie rein theoretisch manuell alle Bilder herunterladen. Ein Download von 100 Bildern auf einmal is auch möglich, leider sind diese Bilder dann nicht in der vollen Auflösung.
Um das zu automatisieren, benötigen wir nur einige Zeilen PHP Code. Nach der Installation der app auf ihrem iPad oder iPhone, öffnen sie einfach die URL, welche die App anzeigt. In der Regel hat die URL ein Format wie folgt:
http://192.168.1.6:15555/0/fr_564.jpg
Die erste “0” im URL steht für die ID des Fotoalbums. Wenn Sei also zwei Alben auf ihrem iPad oder iPhone haben, kann in der URL nur die Werte 0 und 1 vorkommen. Der letzte Teil der URL is der direkte Link zu dem Bild mit der Nummer 564 in voller Auflösung (full resolution). Wir nutzen diese Struktur des URLs um die Bilder automatisch herunterzuladen.
Automatisiertes Herunterladen mit einem PHP Skript
Die folgenden Zeilen PHP Code bewerkstelligen das herunterladen und abspeichern der Bilder auf ihrem lokalen Rechner.
for($k=0;$k
for($i=1;$i
//adjust this
$url = “http://192.168.1.9:15555/”.$k.”/fr_”.$i.”.jpg”;
//adjust this
$fn = “C:/Dokumente und Einstellungen/Thiemo/Desktop/Kolumbien/”.$k.”-“.$i.”.jpg”;
//to make sure you dont redownload a file already downloaded if you want
//to run the script several times
if(!file_exists($fn)) {
if($content = file_get_contents($url)) {
$fp = fopen($fn,”a+”);
fwrite($fp, $content);
fclose($fp);
}
}
}
Weiterführende Links:
]]>SELECT distinct(location) as loc, count(*) as nobs FROM `coztias` GROUP BY loc ORDER BY `nobs` DESC
Das heißt hier ermitteln sie zunächst die verschiedenen Orte oder Länder aus denen ihre Mitglieder sind über die distinct() Funktion. Durch das Group by Statement wird sichergestellt, dass die count() Funktion auf diese Gruppen angewendet wird.
loc | nobs |
---|---|
279 | |
china | 237 |
188 | |
singapore | 88 |
gibraltar | 88 |
japan | 80 |
us gulf | 73 |
far east | 72 |
shanghai | 67 |
xingang | 59 |
north china | 58 |
Weiterführende Links:
]]>In PHP wäre die Umsetzung über die preg_replace Funktion, etwa wie folgt:
$dely = preg_replace('/([a-z])([A-Z])/', '$1 $2', $dely);
Man kann das noch etwas variieren, sodass auch Worte, die etwa direkt auf Zahlen folgen, mit einem Leerzeichen getrennt werden.
Weiterführende Links:
]]>function ResponseToArray($response) { return json_decode($response,true); } function findLocation($string) { $url = "http://maps.google.com/maps/geo?q=".urlendcode($string) ."&output=json&sensor=true_or_false&key=your_api_key"; $raw = file_get_contents($url); $geodata = ResponseToArray($raw); $point = $geodata["Placemark"][0]["Point"]["coordinates"]; return $point; }
The use is relatively simple, the function only has to pass an address as a string. A call to the function might look like this:
$ points = findLocation ("Tiergarten Berlin"); pre> Acording to https://www.igloosoftware.com/solutions/culture_and_engagement, HR admins can also set initial leave allowances, schedule leave allowance increases by date, and make offsets for earned or used leave. Admins can add multiple e-mails to receive leave requests for approval, which can be set to Pending, Approved, Denied or Discuss. The longitude and latitude of the address are returned. The JSON Object is converted into an easy-to-use array using the ResponseToArray function. The complete JSON response also includes additional information that may be used for a map system such as ARCGIS. For example, the next larger administrative unit, i. the state.{ "name": "Tiergarten Berlin", "Status": { "code": 200, "request": "geocode" }, "Placemark": [ { "id": "p1", "address": "Tiergarten, Berlin, Deutschland", "AddressDetails": { "Accuracy" : 4, "Country" : { "AdministrativeArea" : { "AdministrativeAreaName" : "Berlin", "SubAdministrativeArea" : { "Locality" : { "DependentLocality" : { "DependentLocalityName" : "Tiergarten" }, "LocalityName" : "Berlin" }, "SubAdministrativeAreaName" : "Berlin" } }, "CountryName" : "Deutschland", "CountryNameCode" : "DE" } }, "ExtendedData": { "LatLonBox": { "north": 52.5414820, "south": 52.4987120, "east": 13.3775360, "west": 13.3112690 } }, "Point": { "coordinates": [ 13.3427399, 52.5254980, 0 ] } } ] }No related posts.
]]>
Die API von Twitter wurde 2007 veröffentlicht. Mittlerweile gibt es natürlich auch eine PHP Programmbibliothek, mit der Sie Twitter z.B. in Ihr Blog integrieren können. Auf Dr.Web.de wurde ein kleines WordPress Plugin vorgestellt, mit dem man automatisch Nachrichten an Twitter senden kann. Das ganze Skript können Sie hier herunterladen.
Es besteht aus einer Datei. Einem Script, um die Nachrichten an Twitter zu senden und einem Formular, über welches die Nachrichten eingegeben werden.
Der PHP Code für das Senden der Message ist wie folgt:
insertTwitterMsg.php
<?php
$twitter_username ='yourTwitterUserName';
$twitter_psw ='yourTwitterPassword';
require('twitterAPI.php');
if(isset($_POST['twitter_msg']))
{
$twitter_message=$_POST['twitter_msg'];
if(strlen($twitter_message)<1){
$error=1;
} else {
$twitter_status=postToTwitter($twitter_username, $twitter_psw, $twitter_message);
}
}
?>
Hier müssen Sie lediglich ihren Twitter-Benutzername sowie ihr Twitter Passwort anpassen. In der ersten Zeile wird die Twitter API eingefügt. Diese ist ebenfalls in der ZIP Datei enthalten. Daraufhin folgt eine Überprüfung ob die Message auch mindestens ein Zeichen enthält. Wenn nicht, spuckt das Skript eine Fehlermeldung us.
Ansonsten wird die Nachricht an Twitter über die Funktion postToTwitter()
gesendet; diese steckt in der Twitter API. Das Formular, über welches die Messages eingegeben werden ist ebenfalls in der insertTwitterMsg.php implementiert.
<!-- Send message to Twitter -->
<?php
if(isset($_POST['twitter_msg']) && !isset($error)){?>
<div><?php echo $twitter_status ?></div>
<?php } else if(isset($error)){?>
<div>Error: please insert a message!</div>
<?php }?>
<p><strong>What are you doing?</strong></p>
<form action="insertTwitterMsg.php" method="post">
<input name="twitter_msg" type="text" id="twitter_msg" size="40" maxlength="140"/>
<input type="submit" name="button" id="button" value="post" />
</form>
Sofern in der Umgebungsvariable $_POST['']
die Message noch nicht definiert ist, oder ein Fehler entstanden ist – etwa weil die Nachricht weniger als ein Zeichen hatte, so wird die Fehlermeldung ausgegeben. Ansonsten wird der Twitter Status ausgegeben, welcher besagt, ob die Message erfolgreich übertragen wurde. Daruner wird das Formular ausgegeben. So einfach gehts!
Weiterführende Links:
]]>Vielleicht kennen Sie das Problem? Sie möchten, dass in viel HTML Code, z.B. aus einer Datenbank, automatisch die src-Attribute an img-Tags angepasst werden. Sei es z.B., dass aus
<img src="/images/bild.jpg" alt="Ein Bild" /> automatisch <img src="http://www.testseite.de/images/bild.jpg" alt="Ein Bild" />
werden soll.
Jetzt sind Sie sich aber nicht sicher, ob sie wirklich nur valides HTML verwendet haben? Also es soll auch folgendes ersetzt werden:
<IMG src="test/images/bild.jpg" alt="Ein Bild" />
oder
<imG SRC='mein_blog/images/bild.jpg' alt="Ein Bild">
Folgende Zeilen PHP Code erledigen das gewünschte:
$old = "Alter HTML Code, etwa <img src="/images/bild.jpg" alt="Ein Bild" />
$neue_url = "http://www.testseite.de";
$pattern = '/(<img.+?src=)(["\']?)([^\'"]+?)([^\/]+)(\2.*?\/?>)/is';
$replace = "$1$2".$neue_url."$4$5";
$new = preg_replace($pcre, $replace, $old);
Zu dem Code gibt es noch eine kurze Erklärung. Das zweite Subpattern fängt das linke Quote-Zeichen auf, oder eben keins, wenn keins da ist – falls der HTML code nicht valide ist. Das dritte passt auf den Pfad und wird deshalb ersetzt. Das vierte Subpattern erfasst alles nach dem letzten Slash bis zum Ende des Dateinamens. ‘\2’ ist eine Rückreferenz (“back reference”) und passt auf exakt das gleiche Zeichen wie das zweite Subpattern, also ‘”‘, “‘” oder kein Zeichen. Der Rest versucht alle möglichen Arten von img-Tags zu erfassen: “<img …>”, “<img …/>” und “<img … />”.
So sollte es fuktioieren
Weiterführende Links:
]]>Ein schlichter Onlinechat ist eigentlich schwierig zu realisieren, da die neu eingegangenen Messages stets vom Server geladen werden müssen. Dies bedeutete bisher, dass die Seite neu geladen werden musste. Um dies zu umgehen, hat man auf andere Möglichkeiten gesetzt, wie zum Beispiel JavaApplets. Mit AJAX wird die Sache erleichtert, da man die Seiten nicht mehr neu im Browser laden muss. Die periodische Überprüfung nach neuen Messages kann über JavaScript und XMLHttpRequests mit der setTimeOut-Funktion gesteuert werden.
Hört sich einfach an – ist es im Grunde auch so. Bei Dr.Web wurde bereits einmal von mir ein Skript vorgestellt, mit dem auf einfache Art eine Shoutbox programmiert wurde. Dieses Skript soll nun Schritt-für-Schritt AJAX tauglich gemacht werden und zu einem Chat umfunktioniert werden.
Im Internet gibt es bereits OpenSource-AJAX-Chat-Anwendungen, zum Beispiel Lace und Treehouse. Unser Beispiel wurde entwickelt, um im Rahmen dieser Artikelserie AJAX näher zu bringen. Das Beispiel weist längst nicht alle Features auf, die möglich wären, ist so aber besser verständlich.
Rollen wir das Feld von hinten auf und beginnen wir mit dem so genannten Server Backend. In unserem Fall ist das eine MySQL Datenbank. Für unsere kleine Anwendung verwenden wir eine Tabelle Namens "ajaxChat", welche die Felder id, name, nachricht und date hat; diese kann mit folgender SQL-Anweisung erzeugt werden:
CREATE TABLE `ajaxChat` (
`id` LONGINT NOT NULL AUTO_INCREMENT
,
`name` VARCHAR( 60 ) NOT NULL ,
`nachricht` VARCHAR( 120 ) NOT NULL
,
`date` VARCHAR( 30 ) NOT NULL ,
PRIMARY KEY ( `id` )
);
Zunächst wird das Backend angegangen; zum einen
die Datenbank, zum anderen das PHP-Skript, welches die XML-Antworten auf die
http-Anfragen erzeugt.
Das PHP-Skript (nennen wir es ajaxchat.php) auf der Serverseite muss folgende Funktionalitäten aufweisen:
Die Ausgabe der Daten, das heißt die asynchrone Antwort des Servers erfolgt über XML; dieses wird dann über JavaScript und CSS im Browser dargestellt.
Die Datenbankverbindung kann über folgenden Zeilen-Code geöffnet werden; die Variablen müssen an die jeweilige Serverumgebung angepasst werden.
<?php
//wichtig; damit nicht gecached wird!
header(
"Cache-Control: no-cache, must-revalidate" );
header( "Pragma: no-cache"
);
//damit unser JavaScript die Daten auch als XML
erkennt
header("Content-Type: text/xml");
$db_host = "localhost"; //
Host
$db_user = "root"; // User
$db_password = ""; //
Passwort
$db_name = "test"; //
Datenbank
mysql_connect($db_host,$db_user,$db_password) or
die(mysql_error());
mysql_select_db($db_name) or die(mysql_error());
Nachrichten auslesen
Die Funktion, mit der stets die
aktuellsten Nachrichten aus der Datenbank extrahiert werden:
function getLatestEntries($latestID) {
$query = "SELECT id,
name, nachricht, date FROM ajaxchat WHERE id > $latestID ORDER BY id DESC
LIMIT 20";
$erg = mysql_query($query);
echo "<?xml version=\"1.0\"
encoding=\"UTF-8\" standalone=\"yes\"?>";
echo
"<messages>";
while($erg2=mysql_fetch_array($erg)) //Erzeugung der XML
Ausgabe
{
echo "<message><id>".$erg2['id'];
echo
"</id><name>".$erg2['name'];
echo
"</name><nachricht>".$erg2['nachricht'];
//Formatierung des
Timestamps
echo "</nachricht><date>".date("d.m.Y
H:i",$erg2['date']);
echo "</date></message>";
}
echo
"</messages>";
}
Bei dieser Funktion kommt es insbesondere auf die SQL-Abfrage an; über die Bedingung id > $latestID, werden lediglich die Einträge ermittelt, deren ID größer (d.h. deren Einträge "frischer" sind), ermittelt. Die Variable latestID wird, wie wir weiter unten sehen werden, bei dem http Requests über JavaScript übergeben.
Durch den Zusatz ORDER BY id DESC in der SQL Abfrage wird sichergestellt, dass die Einträge absteigend ausgegeben werden; LIMIT 20 beschränkt die Ausgabe auf die letzten zwanzig Einträge. Die Erzeugung des XML-Codes erfolgt schlicht über die echo-Funktion (eine Verwendung der DOMXML Funktionen von PHP wäre bei dem geringen Aufwand nicht gerechtfertigt).
Neue Einträge
Das erzeugen von neuen Einträgen in die
Tabelle erfolgt über folgende Funktion:function
createNewEntry($name, $nachricht) {
//HTML Tags entfernen
$name =
strip_tags($name, '');
$nachricht = strip_tags($nachricht,'');
$query
= "INSERT INTO ajaxchat(name, nachricht, date)
VALUES
('$name','$nachricht','".time()."')";
echo "<?xml version=\"1.0\"
encoding=\"UTF-8\" standalone=\"yes\"?>";
if (!mysql_query($query))
{
//nicht notwendig, dient nur der Fehlerkontrolle
echo
"<createNewEntry>0</createNewEntry>";}
else {
echo
"<createNewEntry>1</createNewEntry>";
}
}
Dabei erzeugt die Funktion createNewEntry wiederum eine XML-Antwort; dieser schenken wir aber keine Beachtung. Sie wurde lediglich zur Fehlerüberprüfung implementiert, so dass man über JavaScript, falls es einen MySQL-Fehler beim Erzeugen eines neuen Eintrag gäbe, dies entsprechend im Browser anzeigen könnte - wenn man denn wollte.
Skriptsteuerung
Da alle Anfragen an ein und dasselbe
Skript geschickt werden (ajaxchat.php), benötigen wir noch ein paar Zeilen-Code,
mit denen sichergestellt wird, dass bei den Aufrufen auch die jeweils
angesprochene Funktion ausgeführt wird. Wir arbeiten hierbei mit Parametern, die
in die http Anfragen über das XMLHttpRequest Objekt eingebaut sind.
//falls action=createNewEntry, Erzeugung eines neuen Eintrages
if
($_GET['action'] == "createNewEntry") {
createNewEntry($_GET['name'],
$_GET['nachricht']);
}
//falls action=getLatestEntries, Ausgabe der
neuesten Einträge
elseif ($_GET['action'] == "getLatestEntries")
{
getLatestEntries($_GET['latestID']);
}
mysql_close(); //schließen der
PHP Verbindung
?>
Das PHP-Skript, der gesamte Backend ist
noch relativ harmlos. Bei unserer AJAX-Engine wird es kniffliger.
Die AJAX Engine
Im zweiten Schritt wird die AJAX-Engine aufgebaut;
mit ihr werden die http-Anfragen erzeugt und die Ergebnisse im Browser
dargestellt
Die AJAX-Engine hat folgende Aufgaben:
Da später das Empfangen von Daten automatisiert wird beziehungsweise über die setTimeOut-Funktion gesteuert wird, ist es notwendig, dass wir für unsere Anwendung zwei XMLHttpRequest-Objekte erzeugen. Damit wird sichergestellt, dass man gleichzeitig sowohl Daten empfangen als auch senden kann.
Erzeugung zweier XMLHttpRequest-Objekte
Das JavaScript
zur Erzeugung der XMLHttpRequest-Objekte ist identisch mit dem aus Teil 2
dieser Artikelserie:<script type="text/javascript">
var
latestID = 0; //latestID als globale Variable; wichtig!
function
createXMLHttpReqObj() { //erzeugt die XMLHttpRequest Objekte
// für
Mozilla etc.
if(window.XMLHttpRequest) {
try { //Fehler abfangen
req =
new XMLHttpRequest();
} catch(e) {
req = false;
}
// für den
InternetExplorer
} else if(window.ActiveXObject) {
try {
req = new
ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new
ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req =
false;
}
}
}
return req;
}
// Initialisierung der beiden
Objekte
var httpGetLatestEntries= createXMLHttpReqObj();
var
httpCreateNewEntry = createXMLHttpReqObj();
Neueste Einträge abfragen
Bei der Abfrage nach den
neuesten Einträgen wird die LatestID in der http-Anfrage mit
übergeben. Diese ist eine globale Javascript-Variable, da ihr Wert aus
Funktionen heraus geändert wird. Initialisiert wird sie mit dem Wert null. Die
URL zu dem Skript ajaxchat.php müssen Sie natürlich an Ihre Umgebung
anpassen.
Die Funktion getLatestEntries sieht wie folgt aus://Funktion,
mit der Anfragen nach neuen Einträgen gesendet wird
function
getLatestEntries() {
//Anfrage senden, wenn Status der letzten Anfrage
"completed" ist, bzw. "nicht initialisiert" (d.h. erster Aufruf)
if
(httpGetLatestEntries.readyState == 4 || httpGetLatestEntries.readyState == 0) {
//Übergabe der
latestID
httpGetLatestEntries.open("GET","
http://localhost/ajax/ajaxchat.php?
action=getLatestEntries&latestID="+latestID,
true);
httpGetLatestEntries.onreadystatechange = handleHttpGetLatestEntries;
httpGetLatestEntries.send(null);
}
}
Als Funktion, mit welcher der Browser die Serverantwort behandelt ist die Funktion handleHttpGetLatestEntries angegeben:
//Behandelt die Serverantwort
function handleHttpGetLatestEntries()
{
//wenn Anfrage den Status "completed" hat
if
(httpGetLatestEntries.readyState == 4) {
//ermitteln der Antwort
response
= httpGetLatestEntries.responseXML.documentElement;
//ermitteln der
Messages; Überführung in ein Array
messages =
response.getElementsByTagName('message');
//wenn es mindestens eine neue
Nachricht hat, dann wird diese angezeigt!
if(messages.length > 0)
{
for (var i=messages.length-1; i>=0; i--) {
//Darstellung im
Browser mit dem DOM
showEntry=
document.getElementById("showEntries");
neuSpan =
document.createElement('span');
neuSpan.setAttribute('class','entry'); //CSS
Klasse
neuSmall = document.createElement('small');
neuNameDate =
document.createTextNode(messages[i].getElementsByTagName
('date')[0].firstChild.nodeValue
+ ': ' + messages[i].getElementsByTagName('name')[0].firstChild.nodeValue +':
');
neuSmall.appendChild(neuNameDate);
neuSpan.appendChild(neuSmall);
neuSpan.appendChild(document.createElement('br'));
neuNachricht =
document.createTextNode(messages[i].getElementsByTagName
('nachricht')[0].firstChild.nodeValue);
neuSpan.appendChild(neuNachricht);
neuSpan.appendChild(document.createElement('br'));
showEntry.insertBefore(neuSpan,
showEntry.firstChild);
}
//Festlegung der neuen latestID; Zugriff auf
die Werte über das DOM
latestID =
messages[0].getElementsByTagName('id')[0].firstChild.nodeValue;
}
//erneuter periodischer Aufruf (eine Art
Rekursion)
setTimeout('getLatestEntries();',3000); //Erneute Anfrage in drei
Sekunden
}
}
Über diese wird, sofern die Anfrage erfolgreich
war, die XML-Daten vom Server in ein Array (messages) überführt und im Browser
dargestellt. Dies findet jedoch nur statt, wenn es auch neue Nachrichten zum
Anzeigen gibt (wenn messages.length >0), das heißt wenn die Anfrage an das
PHP-Skript auch eine neue Nachricht zurückgegeben hat. Ist dies der Fall, wird
die latestID nach der Darstellung der neuen Nachrichten im Browser aktualisiert.
Da dies aus einer Funktion heraus geschieht, wird klar, weshalb latestID eine
globale Variable sein muss.
Über die setTimeOut-Funktion wird nun unsere periodische Überprüfung nach neuen Einträgen durch den Aufruf der Funktion getLatestEntries alle drei Sekunden initialisiert; dabei handelt es sich um eine Art "verzögerte Rekursion".
Neue Nachrichten eintragen
Die JavaScript Funktionen,
über welche neue Einträge an den Server gesendet werden, sind ähnlich aufgebaut,
wie die vorherigen Funktionen. Mit der ersten Funktion createNewEntry wird die
http-Anfrage erzeugt, wobei ihr die Werte für die Felder name und nachricht aus
dem HTML-Formular übergeben werden. //neue Nachricht auf dem
Server erzeugen; die Übergabe der Werte erfolgt über das HTML
Formular
function createNewEntry(name, nachricht) {
//Anfrage senden,
wenn Status der letzten Anfrage "completed" ist, bzw. "nicht initialisiert"
(d.h. erster Aufruf)
if (httpCreateNewEntry.readyState == 4 ||
httpCreateNewEntry.readyState == 0) {
//URL für HTTP Anfrage; muss angepasst
werden
url =
'http://localhost/ajax/ajaxchat.php?action=createNewEntry&name=' + name +
'&nachricht=' + nachricht;
httpCreateNewEntry.open("GET", url,
true);
httpCreateNewEntry.onreadystatechange =
handleHttpCreateNewEntry;
httpCreateNewEntry.send();
}
}
Die Antwort vom Server wird über die Funktion handleHttpCreateNewEntry
abgearbeitet; diese ist relativ kurz:
//behandelt die Antwort des Servers
function
handleHttpCreateNewEntry() {
if (httpCreateNewEntry.readyState == 4)
{
//nachdem eine neue Nachricht erfolgreich erzeugt wurde, wird diese
angezeigt
getLatestEntries();
}
}
Nachdem die Daten erfolgreich in der Datenbank hinterlegt wurden, wird die Funktion getLatestEntries() wiederum aufgerufen, um sicherzustellen, dass die neue Nachricht auch sofort angezeigt wird.
Das Frontend
Nachdem nun die AJAX-Engine aufgestellt ist,
wenden wir uns dem Frontend zu. Auch hier ist JavaScript gefragt. So können die
Eingaben über JavaScript überprüft werden; die Darstellung der Nachrichten kann
über eine CSS-Klasse beeinflusst werden.
Das Formular
Das Formular ist simpel gehalten; es gibt
lediglich Eingabefelder und einen Submit-Button:
<form name="form1" method="post"
action="">
<p>Name<br />
<input type="text" name="name"
id="name">
<br />
<br />
Nachricht<br
/>
<input type="text" name="nachricht"
id="nachricht">
</p>
<p>
<input type="submit"
name="Submit" value="Submit" onclick="checkInput(document.form1.name.value,
document.form1.nachricht.value)" >
</p>
</form>
Nachdem man auf den Submit-Button geklickt hat, wird die JavaScript-Funktion checkInput aufgerufen; an diese werden die eingegebenen Daten weitergegeben. In ihr wird die Eingabe überprüft.
Eine solche Überprüfung könnte im einfachsten Fall wie folgt
aussehen:function checkInput(name, nachricht) {
if(name != ""
&& nachricht != "") {
//Falls alles OK ist, kann der neue Eintrag
erzeugt werden
createNewEntry(name, nachricht);
}
else
{
alert("Bitte sowohl einen Namen, als auch eine Nachricht
eingeben!");
}
}
Die Darstellung der Ergebnisse kann mit Hilfe von CSS beeinflusst werden. Dazu greifen wir auf die über das DOM zugewiesene CSS-Klasse "entry" zurück; über folgende Zeilen könnte man die Darstellung im Browser ein wenig ansehnlicher machen.
<style type="text/css">
.entry {
width:
100%;
background-color: #F5F5F5;
border: 1 dotted #666666;
font-family:
Verdana;
}
.entry#small {
color:
#CCCCCC;
}
</style>
So könnte das Ergebnis im Browser
aussehen:
AJAX Chat in der konkreten
Anwendung
Der Aufruf des Skriptes kann über einen onLoad-Event im Body-Tag der
HTML-Seite (<body onload="getLatestEntries()">), in welcher das Formular
eingebettet ist, eingeleitet werden; dabei wird die Funktion getLatestEntries
das erste mal aufgerufen, wodurch die setTimeOut-Endlosschleife gestartet wird.
Alles in allem, war es ein langer Weg von der Idee zur konkreten
Umsetzung. AJAX bedeutet nicht nur, dass die Webseiten in Zukunft in ihrem
Verhalten normalen Desktop-Anwendung ähneln können, sondern
bringt auch viel Arbeit mit sich. Vor allem das Zusammenspiel von JavaScript und
XML klappt bislang nicht immer reibungslos.
Das hier vorgestellte Beispiel besitzt zudem einen Bug, der nicht verschwiegen werden darf. Auf der JavaScript Seite kann nicht mit Umlauten oder anderen Sonderzeichen umgegangen werden; diese verursachen einen Fehler. Alle Dateien gibt es wie immer als Paket zum Download.
(tf)
Dieser Artikel ist ebenfalls bei Dr.Web erschienen
Weiterführende Links:
]]>In herkömmlichen Webanwendungen werden Formulare ausgefüllt und abgeschickt. Bis dies geschieht, bleiben die Daten auf der Clientseite, der Server bekommt nicht mit, dass Daten in das Formular gefüllt werden. Stürzt nun der Browser mitten während des Ausfüllens ab, sind die Daten verloren, da sie ja nicht abgeschickt wurden.
Ein solches Szenario kann man mit dem Ansatz von AJAX verhindern. Dabei werden bereits während des Ausfüllens von Formularen asynchron die Daten zum Server über das Javascript Objekt XMLHttpRequest geschickt.
Die Kommunikation kann auch anders herum erfolgen; das heißt, wenn der Benutzer zum Beispiel Daten eingibt, wie die Postleitzahl, so kann der Server direkt nach dem Eingeben der Postleitzahl in einer Datenbank nach dem korrespondierenden Ortsnamen suchen und diese im Formular anzeigen. Das heißt man muss Änderungen im Formular nicht mehr explizit abschicken, das wird im Hintergrund erledigt.
Zum einen wird damit die Serverlast ein wenig heruntergeschraubt, da die Daten in kleinen Paketen gesendet werden, zum anderen wird das Ausfüllen und Absenden von Formularen beschleunigt. Dieser Ansatz wird als Asynchronous Javascript and XML bezeichnet – kurz AJAX; dabei ist AJAX keine eigene Technologie, sondern lediglich eine Kombination von bereits existierenden und profilierten Technologien. AJAX wird bereits ausgiebig im Internet, unter anderem von Google und Co. verwendet.
Das wohl bekannteste Beispiel ist Google Suggest. Dabei wird bereits während der Eingabe eines Suchstrings nach etwaigen Ergänzungen gesucht und die voraussichtliche Ergebniszahl zu dem Suchbegriff angezeigt. Das Ganze funktioniert, während man im Suchfeld Suchbegriffe eingibt. So kann man schon vorweg sehen, ob es sich lohnt, die Suche genauer zu spezifizieren, sollten sich etwa zu viele Suchergebnisse finden.
Google Suggests - Während der Eingabe werden von
Google Vorschläge für die Suche angezeigt
Mit dem AJAX-Ansatz könnte man das Stop-and-Go-Verhalten von Webapplikationen umgehen; der Benutzer muss nicht mehr auf den Server warten, da alles im Hintergrund geregelt wird.
Über das XMLHttpRequest Objekt ist es möglich, über JavaScript und XML mit Webapplikationen, die auf dem Server laufen, zu interagieren. Dabei werden die Daten, zum Beispiel aus Formularen in Form von HTTP-Anfragen versendet. Das funktioniert ähnlich wie mit SOAP oder generell wie bei Webservices, nur das hier über JavaScript mit einer Applikation asynchron kommuniziert wird. Die Antworten des Servers werden in Form von XML versandt.
Im Modell sieht die klassische Client-Server Interaktion im zeitlichen Verlauf etwa wie folgt aus.
Klassisches Modell der
Client-Server-Kommunikation; Dateneingabe und Datenverarbeitung auf dem Server
verlaufen synchron
Dabei werden die Zeitverzögerungen, die sich aufgrund des Sendens und
Empfangens von Anfragen beziehungsweise Antworten deutlich.
Mit dem
AJAX-Ansatz wird eine weitere Engine eingebaut, die den Versand der Daten
asynchron regelt. Wie man aus der Modellskizze erkennen kann, werden zum
Beispiel die Daten aus der ersten Eingabe noch serverseitig verarbeitet, während
zur selben Zeit bereits wieder neue Daten eingegeben werden können. Der Versand
wird über die AJAX-Engine geregelt.
AJAX-Modell - Dateneingabe und Datenverarbeitung auf dem Server
verlaufen asynchron
Das für die Kommunikation notwendige XMLHttpRequest-Objekt wurde zunächst von
Microsoft als ActiveX entwickelt, ist aber heutzutage in allen gängigen Browsern
integriert. Es ist der Kern des AJAX-Ansatzes, da mit ihm die Client-Server
Kommunikation, die im Hintergrund abläuft, ermöglicht wird. Jedoch liegt der
Fokus bei AJAX nicht allein bei XMLHttpRequest, sondern grundsätzlich bei der
Idee des Zusammenspiels der verschiedenen Technologien.
Ablauf einer Anfrage über XMLHttpRequest
Im
InternetExplorer wird XMLHttpRequest immer noch über ein AcitiveX-Objekt
initialisiert, während es in Browsern wie Mozilla als einfaches Objekt
abgeleitet werden kann.
Da AJAX verstärkt über XMLHttpRequest Javascript als Technologie integriert, ergeben sich jedoch auch Probleme. So muss, zum Beispiel gerade schon bei der Initialisierung eines Objektes auf die Besonderheiten der verschiedenen Browser geachtet werden. Dadurch können die Skripte mitunter recht komplex ausfallen und man muss sich fragen, ob sich der Aufwand überhaupt lohnt. Der "Zurück"-Button des Browsers wird ebenfalls bei der Verwendung einer solchen AJAX Technologie unnutzbar, da dieser ja nur über die direkten Anfragen des Clients funktioniert.
Des Weiteren ergeben sich mit AJAX auch Probleme etwa für die barerierearmen Gestaltung von Webformularen, da AJAX nicht den Anforderungen der Web Accesibility Initiative des W3C entspricht und auch nur schwer kompatibel gemacht werden kann.
Dennoch ergeben sich den Programmierern von Webapplikationen mit AJAX viele neue Möglichkeiten. Die Webapplikationen werden immer ähnlicher zu herkömmlichen Desktop-Applikationen, was auch zu deren Emanzipation beitragen kann. Auf jeden Fall unterstützt AJAX die weitergehende Entwicklung von Webtechnologien. (tm)
(tf)
Dieser Artikel ist ebenfalls bei Dr.Web erschienen
Weiterführende Links:
]]>