Hallo zusammen,
ich habe mir einen simplen Webserver mit Node fürs RPi aufgebaut und
kann jetzt im eigenen Wlan meine Rolläden steuern.
Das ganze ist fern jeglicher Softwarearchtitektursvorgaben, aber es
funktioniert :-)
Wenn ich den Server Anfrage, gibt er mir die index.html mit
html-Formularen mit get-Anfragen und diese kann ich dann via Button auch
ausführen.
Wenn ich jetzt den Browser (zumindest auf dem Android Smartphone)
schließe und anschließend öffne, führt er die letzte get-Anfrage
nochmals aus.
Ist das so gewollt? Kann ich das verbieten?
Welcher Quellcode gibt ggf. weiteren Aufschluß, dann packe ich ihn dran.
Das Verhalten der Browser unter Android scheint so zu sein, dass bei
erneutem Aktivieren des Browsers die zuletzt dargestellte Seite neu
geladen wird.
Workaround:
Einen leeren Tab öffnen, danach den Browser verlassen.
deshalb verwendet man für Sachen die Seiteneffekte auf dem Server haben
POST und nicht GET.
GET ist allein dazu da um Sachen vom Server abzurufen, daher auch der
Name. Der Browser kann nicht wissen dass bei einem GET auf dem Server
die Rolläden verrückt spielen, er geht davon aus dass er die selbe
Ressource mit GET so oft abrufen kann wie er will ohne daß das
Nebenwirkungen hat.
Bernd K. schrieb:> deshalb verwendet man für Sachen die Seiteneffekte auf dem Server haben> POST und nicht GET.
naja, ich würde die Gets über Ajax senden, dann kennt der Browser die
URL nicht und ruft sie auch nicht ein 2.mal auf.
Peter II schrieb:> naja, ich würde die Gets über Ajax senden
Ich würde es mit POST machen so wie es vom Erfinder vorgesehen war und
nicht krampfhaft ein GET zu etwas vergewaltigen wozu es niemals gedacht
war und dann die abenteuerlichsten Verrenkungen anstellen um die daraus
erwachsenen Komplikationen zu umschiffen.
Bernd K. schrieb:> Ich würde es mit POST machen so wie es vom Erfinder vorgesehen war und> nicht krampfhaft ein GET zu etwas vergewaltigen wozu es niemals gedacht> war und dann die abenteuerlichsten Verrenkungen anstellen um die daraus> erwachsenen Komplikationen zu umschiffen.
nur das das alles vor Javascript war. Die Zeiten ändern sich. Get hat
für mich den Vorteil des ich es einfach in der URL testen kann und im
accesslog auch gleich die Parameter für eine Diagnose sehen.
Post würde ich erst bei vielen Daten einsetzen. (oder wenn ein Passwort
übertragen werden soll)
Das war halt meine Intension,
ich kann ja mal meinen unsauberen Code des Servers zeigen,
ist halt "schön" knapp gehalten alles.
Bei der generellen Anfrage, soll er die Index.html bekommen und mit der
get-Anfrage an index.html arbeitet er dann für mich.
->res.send("Fehler, keine Daten übertragen.");
Soll eigentlich mein "Error-Handler" sein, wenn man index.html ohne
Parameter aufruft.
Den Error-Handler von exec habe ich via Copy&Paste mit übernommen....
var express = require('express');
var app = express();
var path = require('path');
var exec=require ("child_process").exec;
var port= 8080;
app.get('/', function (req, res) {
res.sendfile(path.join(__dirname + '/index.html'));
});
app.get('/index.html', function (req, res) {
var befehl = req.param("Rollobefehl");
if (befehl) {
exec("sudo /home/pi/rcswitch-pi/send "+befehl, function(error, stdout,
stderr) {
if (error) {
console.error("exec error: ${error}");
return;
}
console.log("stdout: ${stdout}");
console.log("stderr: ${stderr}");
});
console.log(befehl);
} else
{
res.send("Fehler, keine Daten übertragen.");
}
});
app.listen(port, function () {
console.log('Hompie hört auf Port: '+port+'!');
});
wichtig ist was in index.html drin steht.
Dort hast du links drin, das würde ich ändern in dem dort JavaScript
aufrufe drin stehen. Dann wird die Seite nicht neu geladen und der
Browser sieht vom der aktion nichts in seiner URL. Damit ruft er sie
auch nicht ein zweites mal auf.
dann eine Funktion myAction schreibe, dort mit jXquery oder
xhtXmlreqeust den get-request senden.
(bin jetzt nicht der HTML Profi, sind bestimmt Fehler drin)
Thomas schrieb:> bgcolor> <font face="Verdana">
Das ist aber antiker Code. Den solltest du in einem Museum ausstellen
lassen. Schau dir mal CSS an...
Üblicherweise sendet man heute einen eindeutigen Wert (Token) mit, wenn
am Server was geändert werden soll (u.a. um CSRF zum verhindern). Nach
dem Senden verwirft der Server den Wert, erzeugt einen neuen und
informiert den Client über den neuen Wert, mit dem er wieder was ändern
kann.
Hier im Forum ist das z.B.
Also das mit CSS verstehe ich schon, wollte mir das aber erst im
Nachhinein anschauen. Erst sollte es funktionieren, dann schön aussehen
:-)
jQuery war auch als Schritt zwei gedacht.
Also zusammenfassend.
So wie es jetzt ist, wird es nicht besser, aber für mich ist es im
Heimnetz ja erstmal okay.
Als nächstes Versuche ich mich dann an jQuery und dann CSS :)
Ist das mit dem Token wirklich notwendig, wenn doch im Heimnetz alles
überschaubar ist?
Irgendwann kommt dann danach (sollte eigentlich das nächste sein) die
Einbindung der DB, damit ich die Änderungen nicht "vergesse".
Thomas schrieb:> Ist das mit dem Token wirklich notwendig, wenn doch im Heimnetz alles> überschaubar ist?
wenn du es mit Ajax machst, dann nicht. Dort kann man das ja im Code
verhindern.
wenn "befehl" den string "; rm -rf /" enthält könnte es lustig werden.
am besten case/switch auf den string verwenden, und die entsprechende
operation dann statisch ausführen - ohne concatenierung.
Thomas schrieb:> Wenn ich jetzt den Browser (zumindest auf dem Android Smartphone)> schließe und anschließend öffne, führt er die letzte get-Anfrage> nochmals aus.>> Ist das so gewollt? Kann ich das verbieten?
Du kannst verhindern, indem Du nach erfolgreicher Abarbeitung eines
Befehls einen Redirect auf die index.html ohne Parameter machst.
Thomas schrieb:> Ist das mit dem Token wirklich notwendig, wenn doch im Heimnetz alles> überschaubar ist?
Nein, Du nimmst einfach POST statt GET und Dein Problem aus Post #1 ist
gelöst.
Bernd K. schrieb:> Thomas schrieb:>> Ist das mit dem Token wirklich notwendig, wenn doch im Heimnetz alles>> überschaubar ist?>> Nein, Du nimmst einfach POST statt GET und Dein Problem aus Post #1 ist> gelöst.
So hätte man das in den 90er Jahren gemacht. POST ist vorallem dazu
gedacht, Formulardaten zu übertragen.
Heutzutage macht man das sehr elegant mittels JavaScript und AJAX oder
sogar noch einfacher mit jQuery (welches darauf aufsetzt).
Es hat den Vorteil, dass die Webseite nicht bei jeder Interaktion frisch
geladen werden muss und erlaubt dadurch eine sehr zügige Bedienung.
Johnny B. schrieb:> So hätte man das in den 90er Jahren gemacht. POST ist vorallem dazu> gedacht, Formulardaten zu übertragen.>> Heutzutage macht man das sehr elegant mittels JavaScript und AJAX oder> sogar noch einfacher mit jQuery (welches darauf aufsetzt).> Es hat den Vorteil, dass die Webseite nicht bei jeder Interaktion frisch> geladen werden muss und erlaubt dadurch eine sehr zügige Bedienung.
So ein junger Hupfer...
Schon in den 90er Jahren hat man sich gedacht, dass das Neuladen der
Seite bei vielen Form-Posts unnötig ist, und hat deshalb den
HTTP-Response-Code 204 eingeführt.
Ich weiß, uncool Sachen so zu benutzen, wie sie gedacht waren...
Johnny B. schrieb:> So hätte man das in den 90er Jahren gemacht. POST ist vorallem dazu> gedacht, Formulardaten zu übertragen.
HTTP weis doch überhaupt nichts von Formularen. Der Nachteil von GET
ist, dass es dem Sinne eine Operation ohne Seiteneffekt ist.
Es gibt auch browser, die Laden schon mal alle verlinkten Resourcen auf
Vorrat und tun dies eben mit HTTP GET. Im beschriebenen Fall, könnte ein
Browser die Bewegung der Rollläden allein dadurch auslösen, dass er eine
Seite sieht, auf der ein Link zur besagten URL steht.
Auch ein HTTP POST/PUT/DELETE läßt sich relativ einfach testen, wenn man
für nur das richtige Werkzeuge nimmt (z.B. wget oder curl).
> Heutzutage macht man das sehr elegant mittels JavaScript und AJAX oder> sogar noch einfacher mit jQuery (welches darauf aufsetzt).
Das hat aber nichts mit der Diskussion GET vs. POST zutun. Auch ein
asynchroner HTTP request kommt beim Webserver nur als request an. Und
auch dort hat der HTTP request eine Method zu haben und die sollte im
obigen Fall einfach kein GET sein.
Planlos schrieb:> So ein junger Hupfer...>> Schon in den 90er Jahren hat man sich gedacht, dass das Neuladen der> Seite bei vielen Form-Posts unnötig ist, und hat deshalb den> HTTP-Response-Code 204 eingeführt.>> Ich weiß, uncool Sachen so zu benutzen, wie sie gedacht waren...
kann ich auch noch nicht. Aber damit kann man keine schöne
Warte-Animation zeigen.
c.m. schrieb:> wenn "befehl" den string "; rm -rf /" enthält könnte es lustig werden.
damit lösche ich Dateien, aber ohne Pfad bringt das nix oder? zudem
müsste ich fs eingebunden haben, oder? Kenne den Befehl nicht, dass ist
nur meine 5 Minuten google Zusammenfassung.
Sheeva P. schrieb:> Du kannst verhindern, indem Du nach erfolgreicher Abarbeitung eines> Befehls einen Redirect auf die index.html ohne Parameter machst.
Das habe ich bei mir ja in der Else Anweisung als Fehler drin. Wäre also
dann blöd :-)
Also dann nochmal für mich zum Verständnis.
1. Get ist Böse in meinem Fall
Alternativen sind entweder über Javaskript (jQuery) oder mittels Post.
Das mit dem CSRF habe ich immernoch nicht ganz verstanden, ich lese mir
morgen mal den Artikel bei Wiki durch. Nach überfliegen der ersten
Zeilen geht es da ja um eine gefälschte Anfrage, was das mit dem Get zu
tun hat, weiß ich nicht.
Thomas schrieb:> Sheeva P. schrieb:>> Du kannst verhindern, indem Du nach erfolgreicher Abarbeitung eines>> Befehls einen Redirect auf die index.html ohne Parameter machst.>> Das habe ich bei mir ja in der Else Anweisung als Fehler drin. Wäre also> dann blöd :-)
Keineswegs. ;-)
> Also dann nochmal für mich zum Verständnis.>> 1. Get ist Böse in meinem Fall
Nein, eigentlich nicht. Du könntest GET benutzen, aber Dein Problem wäre
dann, daß der Browser den letzten GET-Request speichert, beim Neustart
so wieder denselben Request erhält, und natürlich ausführt. Ein
GET-Redirect kann Deinen GET-HTTP-Request aber von seinen GET-Parametern
befreien, und dabei auch andere GET-Parameter setzen -- etwa solche, die
keine "Aktion" anstoßen oder erforderlich machen. Wie zum Beispiel eine
Erfolgs-, eine Warn-, oder eine Fehlermeldung. :-)
> Das mit dem CSRF habe ich immernoch nicht ganz verstanden, ich lese mir> morgen mal den Artikel bei Wiki durch. Nach überfliegen der ersten> Zeilen geht es da ja um eine gefälschte Anfrage, was das mit dem Get zu> tun hat, weiß ich nicht.
Im Endeffekt geht es dabei um eine Art Einmal-Passwort, mit dem ein und
genau dieser eine Request-Response-Zyklus geschützt wird. Das ist nicht
die schlechteste Idee, aber Du solltest den ersten Schritt zuerst, also
besser vor dem Zweiten machen...
Thomas schrieb:> 1. Get ist Böse in meinem Fall
Richtig :)
Thomas schrieb:> Alternativen sind entweder über Javaskript (jQuery) oder mittels Post.
Die erste Antwort ist falsch :(
JQuery entbindet dich nicht davon, eine HTTP Method zu verwenden.
Du kannst natuerlich mehr Hacks/Workarounds einbringen ohne die Ursache
fuer dein Problem zu loesen, aber dafuer die Komplexitaet steigern ;)