Server Side JavaScript Tutorial  

Server Side JavaScript Tutorial Server Side und Frameworks - Teil III

o SJS, JST oder JX?
o Raccoon Extras
o Ein Captcha und was dazu gehört
o MooTools.jx in Action
o Die Template-Klasse von Raccoon

In den vorangegangenen Kapitel habe ich Windows-Setup und das Scripten mit v8cgi und dem Template-Modul behandelt. Im dritten Teil soll v8cgi um die Benefits von Mootools erweitert werden, dafür kommt das schlanke Raccoon Framework zum Einsatz. Raccon befindet sich zwar noch im Beta-Stadium, doch die modifizierte Core aus dem Bundle funktioniert und erlaubt MooTools-Vertraute Virtuosität.

SJS, JST oder JX?

Die Dateien des Frameworks sind gerade im Raccon Github Trunk zum Downladen. Keeto benutzt die Dateiendung JX, welche etwas schlanker als das bisherige .sjs ist, und ich im weiteren adaptieren werde. Dazu müssen einige Einstellungen im Apache .conf vorgenommen werden:

    Einmal im v8cgi Setup:

AddHandler v8cgi-script .js .sjs .ssjs .jst .jx


    und

DirectoryIndex index.php index.cgi index.html index.jx


Raccoon Extras

    Im Raccoon-Trunk (vendor/raccoon/Raccoon/Core) finden wir folgende Dateien:

  • Cache.jx

  • Controller.jx

  • Extras.jx

  • MooTools.jx

  • Template.jx



Als erstes wollen wir etwas mit Extras.jx experimentieren. (Übrigens benötigen alle Klassen von Raccoon die MooTools.jx Erweiterung.) Extras erweitern JavaScript-String-Objekte um eine echo()-Funktion und andere nützliche trim und parse und escape Methoden.

    Folgendes ist damit nun möglich:

//PHP-Style
echo('abc');

//MooTools Style
'abc'.echo();

//Nach Mootools-Art lassen sich Aufrufe "verketten"
'<b>abc</b>'.escape().echo();

//Mootools.jx erweitert das JSON-Objekt umd encode bzw. decode
JSON.encode(request.post).echo();

//Ausgeben vom Variablen-Typ
echo(typeof(this.input));


Wie bereits gehabt starten wir unser Programm in einem Try-Catch-Block. Die Catch-Anzeige ist den Raccoon-Vorgaben entlehnt. Anstatt dem Template-Modul von v8cgi verwenden wir die etwas elegantere Templates-Klasse von Raccoon. Dazu später mehr.

    index.js

try {

include('gd');
include('session');

include('./Raccoon/Core/MooTools.jx');
include('./Raccoon/Core/Extras.jx');
include('./Raccoon/Core/Template.jx');


include('./JxCaptcha.jx');
}
catch (e) {
response.write('<html> \
<head><title>Oops!</title> \
<style>body {font-family: "Helvetica Neue", Arial, sans-serif}</style> \
</head><body> \
<h1>An Error Occurred:</h1> \
<p>'+e+'</p> \
</body></html>');

}

Wir benötigen für ein Captcha zusätzlich die das Grafik- und Session-Modul von v8cgi. Danach die Raccoon-Klassen und anschließend unser Programm.

Vor est möchte ich auf einige Eigenheiten von v8cgi eingehen. Variablen sind grundsätzlich nicht «global» also dateiübergreifend zugänglich, da implementierte Dateien wie Funktionsaufrufe behandelt werden. Dies ist eine Eigenheit von JX. Variablen können per var x = this.x, oder bei Klassen mit exports.ClassName = ClassName wie mit PHP-define als global deklariert werden.
Die andrere Sache ist das Error-Handling, die aktuelle SVN (Revision 600<) unterstützt den Config[ShowErrors] Parameter, aber leider sind die verfügbaren Windows-Builds nicht up to date… Daher der Gedanke auf Linux (und CouchDB) umzusteigen. Wobei ich nach dem Erscheinen von Chrome OS mit Linux-Kern sowieso aufspringen werde.

MooTools.jx in Action

MooTools.jx ist eine für v8cgi modifizierte MooTools-Core der sich (ebenfalls) noch in der Beta-Phase Version 2.0 befindet. Die Core ermöglicht es eleganter und leichter Klassen mit Hilfe von Json zu erstellen. Somit kommen wir zu unserer ersten Klasse:

    JxCaptcha Initialisieren:

// JxCaptcha 10 2009    


this.JxCaptcha = new Class ({

Implements: Options,

options: {
words: ['bauplann','stempel','spartaner','indien','roboter','werbung'],
test_mode : false,
size: {x:340,y:70}
},

initialize: function (options) {

this.setOptions(options);
this.input = request.post;
this.msg = { success:'', warn:'', fail:'', log:'' };
this.passed = session.get('captcha_passed');


Ab hier können wir das gewohnte Framework-gestützte JavaScripting einsetzen. :)

    JxCaptcha.draw() zeichnet das Captcher mithilfe des GD-Moduls:

draw: function (word) {


var image = new Image(Image.TRUECOLOR, this.options.size.x, this.options.size.y);
image.fill(1, 1, Image.trueColor(255,255,255));

var bgimage = new Image(Image.JPEG, 'smoke.jpg');
image.copy(bgimage, 0, 0, 0, 0, this.options.size.x, this.options.size.y);

var angles = [-1.15,-1.1,1,1.1,1.15];
var r1 = angles.random();
var r2 = angles.random();
var r3 = angles.random();
image.string(
Image.trueColor(20,10,5), 'verdana',
40 + (7 * angles.random()),
0.05 * angles.random(),
35 + (10 * angles.random()),
50 + (10 * angles.random()),
word
);


image.save(Image.PNG, new File('captcha.png'));


},

Nach dem Erstellen des Image-Objekts wird das Bild 'some.jpg' als rein kopiert und dient als Hintergrund. Anschließend wird das Wort darauf gezeichnet. Abstände, Schriftgröße und Rotationsgrad variieren.

    JxCaptcha.check() für die Eingabeauswertung über Sessions:

check: function (value) {

var check = value == session.get('captcha_word') ? true : false;
session.set('captcha_passed', check);
session.set('captcha_word', null);
return check;
},

Die Session-Sache ist noch einfacher als beim PHP, zwei Variablen werden gebraucht und und können per get-set gehandhabt werden.

    Anschließend wird das Template aufgerufen.

processView: function () {

response.write(
new Template({path:'layouts/',suffix:'html'}).process('index', {
//input: this.input,
msg: this.msg,
passed: this.passed
}));
}


Der Aufruf funktioniert genau so wie in der Template-Variante von v8cgi. Noch interessanter wird es im Template:

Die Raccoon-Templates

    layouts/index.html

<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<title>JxCaptcha</title>
<!--[if IE]><script src="html5.js"></script><![endif]-->

<style>
section, header, dialog, article { display:block; }
section { width:350px; margin:20px; font:.8em Verdana; }
header { font-weight:bold; }
#msg_blog { padding:4px; }
article { margin-bottom:1em; padding:5px; }
input#therms { width:100%; }
a img { border:1px solid black; }
</style>
</head>
<body>

<section id="tickler">

<header>JxCaptcha</header>

<div id="msg_blog">
<dialog id="success" style="color:green;"><#: this.msg.success||"" #></dialog>
<dialog id="warning" style="color:orange;"><#: this.msg.warn||"" #></dialog>
<dialog id="fail" style="color:red;"><#: this.msg.fail||"" #></dialog>
<dialog id="log" style="color:black;"><#: this.msg.log||"" #></dialog>
</div>


<# if(!this.passed) { #>

<article>
<a href="index.jx"><img src="captcha.png" /></a>
</article>

<article>
<form id="user_form" method="POST" accept-charset="UTF-8" action="">
<label>Try</label>
<input type="text" name="therms" id="therms" value="" />
<input type="hidden" name="submit" value="true" />

<input type="submit" value="Submit">
</form>
</article>

<# } else { #>

<article>
<h1>Page Content</h1>
</article>
<form id="user_form" method="POST" accept-charset="UTF-8" action="">
<input type="hidden" name="reset" value="true" />
<input type="submit" value="Reset">
</form>
</article>

<# } #>

</section>

</body>
</html>
Keetos Template-Sprache ist recht geschickt zu gebrauchen. Der Code wird innerhalb der <# #>-Tags geparst. Variablen können direkt mit <#: var #> augegeben werden. In Kürze wird die Funktionalität um den Einsatz von Includes mit <#@ «xyz.html» #> erweitert.

Wie Ihr seht habe ich im HTML einen Message-Blog eingebaut. Die msg-Variablen über erfolg/misserfolg der User-Eingaben generiere ich in der initialize-Methode von JxCaptcha.

    Hier das komplette Script:

// JxCaptcha 10 2009    


this.JxCaptcha = new Class ({

Implements: Options,

options: {
words: ['bauplann','stempel','spartaner','indien','roboter','werbung'],
test_mode : false,
size: {x:340,y:70}
},

initialize: function (options) {

this.setOptions(options);
this.input = request.post;
this.msg = { success:'', warn:'', fail:'', log:'' };
this.passed = session.get('captcha_passed');

//handle inputs
if (this.input.submit) {

var userinput = this.input.therms ? this.input.therms.rtrim().escape() : '';
//echo(userinput);
if (this.passed = this.check(userinput))
this.msg.success = "Captcha korrekt eingegeben. Weiter gehts.";
else this.msg.fail = "Captcha-Text falsch eingegeben. Nochmal.";
}

//reset nachdem das captcha korrekt eingegeben wurde
else if (this.input.reset) {
session.clear();
this.passed=false;
this.msg.success = "Nochmal probieren?";
}


//create captcha
if (!this.passed) {

var new_captcha = this.options.words.random();
session.set('captcha_word', new_captcha);
this.draw(new_captcha);
}

this.processView();
},

check: functuin(value) { ... },

draw: function(word) { ... },

processView: function () { ... }

});


var captcha = new JxCaptcha();


Soviel zur objektorientierten Programmierung mit JavaScript fürs Backend! d:) Als nächstes muss CouchDB ins Tutorial. Außerdem will ich versuchen v8cgi auf meinem VServer zum laufen zu bringen.

Kommentare (4)

  
+
0
puh, haut ganz schön rein :)
Sehr gute Einleitung!
avatar

BuzzEins

  • vor ungefähr 9 Monaten
+
0
Die Beispiele zu den Tutorials sind endlich online:

webhike.de/labs/v8cgi/
avatar

wildeuter

  • vor ungefähr 10 Monaten
+
0
Kennt ihr Persevere? Bietet auch ein Framework für serverseitige Javascript-Anwendungen. Es setzt dabei auf Java und Rhino auf, einem Javascript-Interpreter in Java.
avatar

BuzzEins

  • vor ungefähr 8 Monaten
+
0
Rhino ist für mich etwas «unterirdisch». ich habe vor etwa vier jahre mit java gearbeitet. aber es ist mir bis her zwei mal passiert dass ich ein projekt nicht zu ende bringen konnte. einmal in java (ein screen captcha für mpeg-filme) und ein paar perl-arbeiten an einem uralten online shop. zum glück beides während praktikas. seit dem lass ich die finger von den programmiersprachen: den perl geht eh unter und java, viel gelobt aber chaotisch. c und c++ währe mein favorit wenn's um höhere programmiersprachen geht. aber um ich da einzuarbeiten bräuchte es ein paar wochen, also bleibe ich lieber bei zend das richtiges einwandfreies programmieren ermöglicht und warte auf server side js, das mir zu langsam geht
avatar

wildeuter

  • vor ungefähr 8 Monaten

 



Ihre Email bleibt unsichtbar


jeder zweite dofollow :)