Formularannahme klappt nicht -WARUM?

Django, Flask, Bottle, WSGI, CGI…
Antworten
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Hi Leute,
was mir mit PHP unter Windows problemlos gelingt, will mir mit Python unter Linux nicht klappen.
Wenn ich das HTML-Skript unter localhost//formular.html aufrufe, ist soweit alles noch in Ordnung. Allerdings klappt der Aufruf des Python-Skriptes nicht.Es wird mir nach Betätigen des Buttons nur der Sourcecode angezeigt.....
Was mache ich falsch...?

Code: Alles auswählen

import cgi
 print "Content-type: text/html; charset=UTF-8"
print                               
 
 
print (""")
      <html>
      <head><title>Übertragung von Formularinhalten</title></head>
         <body>
     <h1>Die übertragenen Daten.</h1>
      """
 
form=cgi.FieldStorage()
s1=form["Anwender"].value
s2=form["Passwort"].value
 
if form.getvalue("Textfeld"):
   text= form.getvalue("Textfeld")
else:
   text= "keine Eingabe"
 
print (" <p>Dein Name lautet, :", s1,"</p>")
print "<p>Passwort : ",s2,"</p>"
 
print ("<p>Der folgende Text wurde eingegeben:",text,"</p>")
print (" </body> </html>")
Erschwerend kommt hinzu,dass mir Eric6 die Instanzierung der Klasse FiledStorage als Syntaxerror meldet......
Zuletzt geändert von Anonymous am Freitag 11. November 2016, 23:31, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@tklustig: Eigentlich sollte ein Syntaxfehler schon in Zeile 2 auftreten weil das ``print`` da nicht am Zeilenanfang steht.

Und das Problem liegt nicht unbedingt in der Zeile mit der Instantiierung, sondern dort fällt dem Compiler auf, dass etwas nicht stimmt. Nämlich das die öffnende Klammer in Zeile 6 kein schliessendes Gegenstück hat, und damit auf das Zeichenkettenliteral ein Name folgt, was syntaktisch nicht erlaubt ist.

Wie hast Du dem Webserver denn gesagt wo CGI-Skripte liegen und ausgeführt statt ausgeliefert werden sollen?

Und willst Du wirklich CGI verwenden? Und das dann auch noch ohne Rahmenwerk?

Edit: Die Klammern bei den ``print``-Anweisungen solltest Du weg lassen. Wenn keine Kommas darin vorkommen sind sie schlicht zweckfrei und wenn Kommas darin vorkommen, dann sind das Tupel und das führt sicher nicht zu der Ausgabe die Du haben möchtest.
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Wenn ich die Klammern weg lasse, meldet er mir sofort einen Syntaxfehler....
Muss meine print-Anweisungen immer in Klammern schreiben...
Und konfiguriert habe ich den Apacheserver, wie auf http://www.gtkdb.de/index_36_2505.html beschrieben....
Klappt trotzdem nicht!
Zuletzt geändert von tklustig am Samstag 12. November 2016, 01:03, insgesamt 1-mal geändert.
BlackJack

@tklustig: Dann hättest Du den Syntaxfehler schon in der zweiten Zeile und die dritte Zeile wäre sinnfrei weil sie keinen Effekt hätte. Und dann sind das auch keine ``print``-Anweisungen sondern Funktionen, also verwendest Du Python 3.

Was übrigens auch ein Fehler ist, ist die fehlende She-Bang-Zeile, damit der Webserver weiss womit das ausgeführt werden soll. Und ist die Datei in den Dateirechten als ausführbar gekennzeichnet? Welche Dateiendung verwendest Du? *.cgi?
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Weist du,wie ich eric6 dazu bringe, python2 zu akzeptieren.
Der Debugger bietet zwar explizit Konfigurationsmöglichkeiten für beide Versionen an.
Interpretiert wird jedoch ausschließlich Python3 - und das nervt....
P.S: Das vom HTMl-Formular aufgerufene Skript nennt sich 'bearbeiten.py'
BlackJack

@tklustig: Mit Eric kann ich leider nicht weiterhelfen. Ich gehöre zu denen die einen ”einfachen” Texteditor bevorzugen.

Ist der Webserver dann auch so konfiguriert das er Dateien mit der Endung *.py in dem Verzeichnis wo das liegt als CGI-Skripte ausführt? Ich glaube bei dem Apache auf meinem Notebook habe ich da nichts geändert, und der hat `~/public_html/cgi-bin/` in den Verzeichnissen der Benutzer, und `/usr/lib/cgi-bin/` für CGIs konfiguriert. Also `http://<host>/cgi-bin/` und `http://<host>/~<user>/cgi-bin/` als URLs. Die Skripte dort müssen als Programme ausführbar sein. Also „executable bit“ gesetzt und die She-Bang-Zeile muss korrekt sein.
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Das ist wohl das Problem. Skripte werden bei mir nur dann ausgeführt, wenn sie im Verzeichnis var/www/html liegen.
Unter Windows packt man einfach alle Skripte (zumindest für HTML-und PHP-Skripte funktioniert das) in den htdocs-Ordner und ruft dann die entsprechende Seite auf.
Damit das ganze dann von außen erreichbar ist, erstellt man einfach die index.php

Code: Alles auswählen

<?php
	if (!empty($_SERVER['HTTPS']) && ('on' == $_SERVER['HTTPS'])) {
		$uri = 'https://';
	} else {
		$uri = 'http://';
	}
	$uri .= $_SERVER['HTTP_HOST'];
	header('Location: '.$uri.'/dashboard/start.html');
	exit;
?>
und das ganze läuft;
zumindest als root bedarf es keinerlei weiterer Konfigurationen, sofern man XAMPP nutzt......

Bei Linux scheint das aber anderst zu laufen==>

Kannst du mir ein leicht verständliches Tutorial empfehlen, wie man den Apache konfigurieren muss,damit Skripte unter Python und PHP laufen?
Zuletzt geändert von Anonymous am Samstag 12. November 2016, 13:21, insgesamt 1-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
BlackJack

@tklustig: Das hat nichts mit Linux vs. Windows zu tun und HTML-Dateien sind keine Skripte. Das hat noch nicht einmal wirklich etwas mit Python vs. PHP zu tun, denn auch bei PHP *als CGI* hättest Du die gleichen Probleme. Nur wird PHP üblicherweise nicht als CGI ausgeführt sondern Apache behandelt das über `mod_php`, also über ein eigenständiges Apache-Modul das speziell für die Ausführung von PHP-Dateien zuständig ist und den PHP-Interpreter direkt verwendet.

CGI dagegen ist eine allgemeinere Schnittstelle die unabhängig von der Programmiersprache ist. Über diese Schnittstelle kann man Webskripte ausführen die in jeder beliebigen Programmiersprache geschrieben sein können, solange sie Daten über die Standardeingabe oder aus Umgebungsvariablen lesen kann und das Ergebnis auf die Standardausgabe schreiben kann. Also zum Beispiel auch Shell-Skripte oder nativ kompilierte C oder Pascal-Programme. Damit können Programme beliebige Dateiendungen haben. Damit stellt sich das Problem wie der Webserver Programme die ausgeführt werden sollen, von solchen unterscheiden kann die als Datei ausgeliefert werden sollen. Und das wird bei Apache üblicherweise dadurch gelöst das man in der Konfiguration die Verzeichnisse festlegt in denen die auszuführenden Programme liegen.

Ich weiss nicht ob Dir wirklich weitergeholfen wäre mit einem Tutorial wie man CGI konfiguriert, weil das eigentlich keiner mehr benutzt. Jedenfalls nicht für Python. Da ist die WSGI-Schnittstelle mittlerweile Standard. Entweder über das Apache-Modul `mod_wsgi` oder ein eigener WSGI-Daemon/-Server für den man den Webserver als Reverse-Proxy konfiguriert. Und für WSGI-Anwendungen verwendet man eigentlich auch immer ein Rahmenwerk. Und wenn es ein Mikrorahmenwerk wie Bottle oder Flask ist. Oder gleich den Klassiker Django.

Was hast Du denn letztendlich vor?

Edit: Du hast da weiter oben ja eine Beschreibung wie man CGI bei Apache auf dem Raspi aktiviert, verlinkt. Was genau funktioniert denn daran nicht?
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Mein Grundproblem liegt darin, dass ich PHP-Skripte ausführen lassen kann, Python-Skripte hingegen nicht -im Zusamenhang mit HTML-Formularen.
Wenn ich also das HTML-Formular und das entsprechende php-Script in den Ordner var/www/html packe und dann mittels

Code: Alles auswählen

<form method="post" action="absenden.php" target="_blank">
aufrufe, funktioniert alles,wie gewollt.
Dasselbe will ich jetzt auch mit Python realisieren, da Python unter einem RasperyPi -anscheinend- komplikationsloser läuft!
Nur:Wenn ich dieselbe Datei, (absenden.py)' -korrekt programmiert natürlich- in diesen Ordner packe, mit denselben Rechten, zeigt mir der Browser nur den Quellcode an.
Ich aber möchte dieselbe Entgegennahme wie beim php-Script.
Auf welche Weise ich das erreiche, interessiert mich eigentlich nur peripher. muss also nicht zwingend über cgi laufen......
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@tklustig: um das selbe Verhalten zu bekommen, mußt Du halt Deinen Apache richtig konfigurieren, etwa
[codebox=ini file=Unbenannt.ini]
<Directory /var/www/html>
Options +ExecCGI
AddHandler cgi-script .py
</Directory>
[/code]
Ob das sinnvoll ist, sei mal dahingestellt. Zusätzlich muß die Datei ausführbar sein, eine Shebang-Zeile enthalten und keine Syntaxfehler.
BlackJack

@tklustig: Ich habe doch lang und breit erklärt dass das mit CGI anders als mit `mod_php` funktioniert und auch warum das so ist. Man kann das jetzt alles so hinbiegen das es ”genau so” wie mit PHP funktioniert, also etwas machen was so nicht vorgesehen ist, und zwar aus IMHO guten Gründen. Oder man beschäftigt sich damit wie Python-Webanwendungen üblicherweise funktionieren. Das ist halt *anders* als PHP. Ebenfalls aus IMHO guten Gründen. Wenn Du etwas willst das genau wie PHP funktioniert, dann nimm doch einfach *PHP*. Ich wüsste nicht warum das auf einem Raspi Komplikationen machen sollte. Das ist letztendlich ein ganz normales Debian.

In Python, mit Bottle als Mikrorahmenwerk könnte das beispielsweise so aussehen:

Code: Alles auswählen

from bottle import default_app, request, view

app = default_app()


@app.get('/')
@view('form.html')
def get_index():
    pass


@app.post('/')
@view('entered_data.html')
def post_index():
    return {
        'user': request.params['user'],
        'password': request.params['password'],
        'text': request.params['text'].strip() or 'keine Eingabe',
    }
Mit `views/form.html`:
[codebox=html5 file=Unbenannt.html]<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Übertragung von Formularinhalten</title>
</head>
<body>
<h1>Das Formular</h1>
<p>
<form method="POST">
<label>Benutzername:</label>
<input type="text" id="user" name="user">
<br>
<label>Passwort:</label>
<input type="password" id="password" name="password">
<br>
<textarea id="text" name="text"></textarea>
<input type="submit" value="Senden">
</form>
</p>
</body>
</html>[/code]
Und `views/entered_data.html`:
[codebox=html5 file=Unbenannt.html]<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Übertragung von Formularinhalten</title>
</head>
<body>
<h1>Die übertragenen Daten</h1>
<p>Dein Name lautet: {{user}}.</p>
<p>Passwort: {{password}}</p>
<p>Der folgende Text wurde eingegeben: {{text}}</p>
</body>
</html>[/code]
Bei den Templates würde man am besten noch ein gemeinsames Basis-Template erstellen, damit man das HTML-Gerüst das in beiden Fällen gleich ist, nicht wiederholen muss. Und ich persönlich verwende statt der in Bottle integrierten Templates gerne Jinja2 als Template-Engine.
BlackJack

Mit Basis-Template:

base.html
[codebox=html5 file=Unbenannt.html]<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Übertragung von Formularinhalten</title>
</head>
<body>
{{!base}}
</body>
</html>[/code]
form.html
[codebox=html5 file=Unbenannt.html]% rebase('base.html')
<h1>Das Formular</h1>
<form method="POST">
<label>Benutzername:</label>
<input type="text" id="user" name="user">
<br>
<label>Passwort:</label>
<input type="password" id="password" name="password">
<br>
<textarea id="text" name="text"></textarea>
<input type="submit" value="Senden">
</form>[/code]
entered_data.html
[codebox=html5 file=Unbenannt.html]% rebase('base.html')
<h1>Die übertragenen Daten</h1>
<p>Dein Name lautet: {{user}}.</p>
<p>Passwort: {{password}}</p>
<p>Der folgende Text wurde eingegeben: {{text}}</p>[/code]
tklustig
User
Beiträge: 12
Registriert: Mittwoch 9. November 2016, 22:05

Well,dann bleibe ich halt doch bei php. Kein gesteigertes Interesse mich bzgl. der Formulareingaben in Python reinzufuchsen;
zumal dbzgl. Tutorials rar gesät sind.
Konzentriere mich dann doch eher auf andere Anwendungsgebiete für Python, z.B. matplotlib(mathematisch - wissenschaftliches Rechnen)
Werde dann ma' eine komplete Kurvendiskussion für python entwickeln :wink:
In diesem Sinne bedanke ich mich für die zahlreichen posts und beende diesen thread als erfolgreich gelöst!
Antworten