Ryan Dahl der Entwickler von Node.js beim Google Tech Talk

Sehr inspirierender Vortrag wie ich finde .. auch wenn man sich dazu mal ne Stunde Zeit nehmen muss. Vor allem erklärt Ryan ausgezeichnet was das besondere an Node.js ist .. node IST asynchrones, Event basiertes programmieren wie man es vielleicht aus dem Frontend kennt wenn man da schon mit Event Listenern und XHR gearbeitet hat außerdem bedeutet Node.js non-blocking Input und Output.

Alles ist Event basiert .. also ein Zugriff auf die Festplatte die vielleicht gerade durch etwas anderes völlig ausgelastet ist führt nicht zu einem Stop im Programm .. vielmehr kann node einfach den Programmablauf fortführen. Wenn dann die angeforderte Datei von der Festplatte gelesen ist gibt es in node eine Callback Möglichkeit auf die man “hören” kann um dann die Daten abzugreifen .. man kann also immer noch etwas anderes tun als einfach nur auf etwas zu warten 🙂

NPM – der Node Package Manager

NPM ist (die) eine Paketverwaltung von Node.js. JavaScript bringt ja von Haus aus wenige Standard Objekte mit .. wenn ihr also einen DOM parsen wollt oder Templating verwenden wollt könnt ihr das aufwendig selbst entwickeln und dabei jede Menge lernen oder ihr greift auf vorhandene Libraries zurück die Node.js erweitern.

Ich spiele gerade mit haml.js herum um Templates anzulegen und diese dann in mein Node Programm einzubinden. Ich habe also wenig Lust oder Zeit mich mit Templating selbst zu beschäftigen .. nehme ein vorhandenes Modul und nutze das.

Die vorhandenen Libraries installiert man am besten mit NPM .. so könnt ihr sicher sein das alle Abhängigkeiten usw. sauber gesetzt sind und ihr mit der Library oder dem Modul arbeiten könnt.

Hier findet ihr eine Auflistung aller Node.js Module. Ob Datenbankanbindung, Middleware, XML Erweiterungen, Parser etc. es sind Stand 2011 mehrere hundert Module die sich in Node.js einbinden lassen.

Den Node Package Manager -> NPM installieren

git clone http://github.com/isaacs/npm.git
cd npm
sudo make install
  • am besten natürlich in eurem Node Folder auf der gleichen Ebene wie node.js selbst
  • jetzt steht euch die Welt der Node Module offen

Ein Node Modul installieren z.b. HAML

npm install hamljs
  • NPM regelt nun alles für euch .. download, Einbindung etc.

Das Modul in euer Programm einbinden

var haml = require("hamljs");
  • an der gleichen Stelle wie z.b. var http = require(‘http’);
  • das wars auch schon .. nun könnt ihr auf die HAML Objekte zugreifen

OnPage Suchmaschinen Optimierung – 10 Grundregeln

  • Baue eine klares Menü, nutze kein Flash, keine Grafiken, stelle sicher daß das Menü auch ohne JavaScript funktioniert
  • KEIN JavaScript im Quelltext, Einbau über den Script Tag, Events über den Event Listener
  • Der Inhalt deiner Seite muss leicht zugänglich, lesbar, semantisch korrekt sein und idealerweise einer Hierachie folgen (h Tags, p Tags, Listen, Tabellen)
  • Pflege für jede Seite einen eigenen Title Tag der den Inhalt der Seite beschreibt
  • Einzigartiger Content ist King, schreibe ausführliche, eigene Texte die zu deinem Angebot passen
  • Keine kryptischen URLs, keine Session IDs in der URL, keine Redirects, keine tiefen Ordnerstrukturen. Der Dateiname soll den Inhalt der Datei beschreiben
  • Wenn Seiten nicht gecrawlt werden sollen nutze die robots.txt
  • Fülle die ALT Attribute deiner Bilder mit einer aussagekräftigen Beschreibung des Bildes
  • Updates sind King, erweitere den Inhalt deiner Seite regelmäßig
  • halte dich an die W3C Standards, Crawler mögen sauberen, validen Code

Kleiner Formhandler in node.js

Das ganze läuft getestet nur unter node 0.41

Und wieder .. die node.js Doku empfiehlt sich

In meiner spärlichen Zeit habe ich etwas mit Formularverarbeitung in node.js rumgespielt .. mein Ziel war es Daten nach der Eingabe abzuspeichern und auf einer Folgeseite wieder auszugeben.

Beschränkt habe ich mich erst mal auf die Node Core Module ohne ein extra Modul (das es sicher gibt) einzubinden.

Die Eingabe erfolgt über ein normales HTML File (input.html) die Form ruft mit der Methode “Post” den Pfad “/formhandler” auf.

Die Eingabe wird dann verarbeitet und in einem .json File abgespeichert. (json.json)

Die Ausgabe erfolgt der Einfachheit halber mit einem AJAX Request auf das JSON File und dem Einsatz von JQUERY (output.html).

Hier könnt ihr alle Files runterladen.

Lesen von vorhandenen Files und Ausgabe

function readFile (req, res, filename) {
  var readFile = path.join(process.cwd(), filename); 
  fs.readFile(readFile, function (err, data) {	
    if(err) {  
      res.writeHead(500, {"Content-Type": "text/plain"});  
      res.end(err + "\n");    
      return;  
    }
    res.writeHead(200); 
    res.write(data, "binary");
    res.end();
  });
}
  • keine Magie 🙂 process.cwd() gibt den aktuellen Pfad auf dem Rechner zurück
  • Errors werden abgefangen
  • Ausgabe per res.write

Schreiben des Files

function writeFile (decoded) {	
  var writeFile = path.join(process.cwd(), SAVEFILE); 
  decoded = util.inspect(decoded);
  fs.writeFile(writeFile, decoded, function(err) {
    if(err) {
	   console.log(err);
	} else {
	   console.log("File gespeichert!");
	}
  });		
}
  • ich ermittle das aktuelle Verzeichnis adde den Dateinamen
  • Errorhandling
  • Konsolenausgabe bei Erfolg

Auslesen des Form Submits und der Rest

function readFormSubmit(req, res) {
  if (req.method  'POST') {
    var fullBody = '';
	req.on('data', function(chunks) {
	  fullBody += chunks.toString();
	});
	req.on('end', function() {
	  var decoded = querystring.parse(fullBody);
	  writeFile(decoded);
          readFile(req, res, "output.html");      
	});
  } else {
    res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
	res.end('Method not supported');
  }	
}
  • per Formsubmit wird /formhandler aufgerufen und daraufhin diese Funktion
  • node.js ist Non Blocking d.h. wenn nicht alle Elemente auf einmal geliefert werden können läuft eine Schleife die auf neue Elemente wartet und diese aufnimmt (req.on -> data)
  • die “chunks” werden zu einem Ganzen zusammengebaut
  • wenn alle da sind wird das File geschrieben
  • danach rufen wir output.html auf

Der komplette Quelltext:

HOST = null; // localhost
PORT = 8000;
SAVEFILE = "json.json";
var sys = require("sys"),  
    http = require("http"),  
    url = require("url"),  
    path = require("path"), 
    querystring = require("querystring"),
    util = require ("util"), 
    fs = require("fs");
function readFile (req, res, filename) {
  var readFile = path.join(process.cwd(), filename); 
  fs.readFile(readFile, function (err, data) {	
    if(err) {  
      res.writeHead(500, {"Content-Type": "text/plain"});  
      res.end(err + "\n");    
      return;  
    }
    res.writeHead(200); 
    res.write(data, "binary");
    res.end();
  });
}
function writeFile (decoded) {	
  var writeFile = path.join(process.cwd(), SAVEFILE); 
  decoded = util.inspect(decoded);
  fs.writeFile(writeFile, decoded, function(err) {
    if(err) {
	   console.log(err);
	} else {
	   console.log("File gespeichert!");
	}
  });		
}
function readFormSubmit(req, res) {
  if (req.method  'POST') {
    var fullBody = '';
	req.on('data', function(chunks) {
	  fullBody += chunks.toString();
	});
	req.on('end', function() {
	  var decoded = querystring.parse(fullBody);
	  writeFile(decoded);
      readFile(req, res, "output.html");      
	});
  } else {
    res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
	res.end('Method not supported');
  }	
}
function startServer() {
  http.createServer(function (req, res) {
    var uri = url.parse(req.url).pathname; //Dateiname
    var filename = path.join(process.cwd(), uri); //Pfad und Filename
    if (uri = '/formhandler') {
      readFormSubmit(req, res);         
    } else {
      path.exists(filename, function (exists) {	
      if(!exists) {  
	    res.writeHead(404, { "Content-Type": "text/plain"});
	    res.end("Not Found");
      } else {
        readFile(req, res, uri);
      }
    });
    }    
  }).listen(PORT, HOST);
  console.log('Server running');
} 
startServer();

Das Programm startet ihr mir -> node formhandler.js
Dann input.html aufrufen .. z.b. so -> http://localhost:8000/input.html und probieren.

Simpler Form Handler in Node.js als ZIP