Auf POST Parameter von AJAX in Cherrypy zugreifen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Hallo zusammen,

ich habe so meine Probleme in Cherrypy auf die Parameter eines POST Requests zuzugreifen.

Ich nutze auf der Clientseite Ajax aus der der prototype.js und auf der Serverseite Cherrypy.

Bei einem GET Request funktioniert soweit alles wie es soll.
Cherrypy liefert den Wert 10 an das element mit der id 'liste' zurück

Clientseitig Javascript/AJAX:

Code: Alles auswählen

function speichern(){	
        new Ajax.Updater("liste", "/speichern?id=10", {method: "GET"}});
}
Serverseitig Cherrypy:

Code: Alles auswählen

class speichern_cl(object):
	
       @cherrypy.expose
       def index(self, id):
                cherrypy.response.headers["Content-Type"]  "text/plain"
                code = id
                return code

Jetzt kommen wir zu meinem Problem. Wie mache ich das mit einem POST Request?

Also Clientseitig mit Javascript/Ajax sieht das bei mir dann so aus:

Code: Alles auswählen


new Ajax.Updater("liste", "/speichern", {
                            method: "POST",
                            parameters: "id=10"
                            });
Tja und serverseitig steh ich auf dem Schlauch:

Code: Alles auswählen

class speichern_cl(object):

            @cherrypy.expose
            def index(self):

                  cherry.response.headers["Content-Type"] = "text/plain"

                  ...
                  
Wie komme ich prinzipiell mit Cherrypy an die Parameter von einem POST-Request ran?


Vielen Dank im Voraus!

Gruß
Andre
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

slapshot1979 hat geschrieben:Jetzt kommen wir zu meinem Problem. Wie mache ich das mit einem POST Request?
Also Clientseitig mit Javascript/Ajax sieht das bei mir dann so aus:

Code: Alles auswählen


new Ajax.Updater("liste", "/speichern", {
                            method: "POST",
                            parameters: "id=10"
                            });
Hallo Andre!

Du kannst zwar mit ``cherrypy.request.method`` herausfinden ob die Daten per POST oder GET übergeben wurden, aber CherryPy macht ansonsten keinen Unterschied zwischen POST und GET.

Ich denke also, dass das Problem im ``Ajax.Updater``-Aufruf zu suchen ist. Vielleicht muss man die Parameter anders übergeben.

mfg
Gerold
:-)

PS: Willkommen im Python-Forum. :-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Danke fürs herzliche Willkommen! :D

Habe meine Requests dann letztendlich doch alle auf GET umgestellt.
Wenn es nicht zu viele Variabeln werden, bleibt es auch noch einigermaßen übersichtlich.

Der Parameteraufruf bei AJAX muss übrigens wirklich anders aussehen.

Den hatte ich ein bisschen verbockt:

Code: Alles auswählen

new Ajax.Request('/some_url', {
        method: 'get', 
        parameters: {company: 'example', limit: 12}
}); 
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

slapshot1979 hat geschrieben:Habe meine Requests dann letztendlich doch alle auf GET umgestellt.
Du willst damit aber hoffentlich *nicht* sagen, dass du Requests, die Daten auf dem Server verändern, über GET absetzt? Das wäre nämlich richtig $evil - dazu solltest du mehr als genug Literatur im Web finden.
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Naja was heisst Daten auf dem Server verändern. Es sind halt im Prinzip nur Variabeln, die für SQL Statements genutzt werden oder die in Datenbanken gespeichert werden sollen.

Es ist auch nicht vorgesehen, dass das Programm im Web läuft.
Das läuft alles lokal auf einem Rechner ab.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

slapshot1979 hat geschrieben:Naja was heisst Daten auf dem Server verändern. Es sind halt im Prinzip nur Variabeln, die für SQL Statements genutzt werden oder die in Datenbanken gespeichert werden sollen.
Ja eben. Für datenverändernde Aktionen gibt es POST.
slapshot1979 hat geschrieben:Es ist auch nicht vorgesehen, dass das Programm im Web läuft.
Das ist keine Ausrede es falsch zu machen. Man kann nie davon ausgehen, dass ein Programm nicht irgendwann erweitert wird und für neue Einsatzgebiete verwendet wird. Daher sollte man es gleich richtig machen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Ok ihr habt mich überzeugt. :D
Wie man meinen vorhergehenden Posts entnehmen lann, hätte ich es ja auch gerne mit POST gemacht, aber da habe ich halt noch meine Verständnisprobleme, wei ich auf der Serverseite mit Cherrypy dann an die übertragenen Parameter komme.

Sobald ich das begriffen habe, werde ich meine aus Zeitdruck entstandenen "Notlösung" noch mal überarbeiten.

Meine Eingangsfrage ist übrigens noch aktuell. :D
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Ich habe zu dem Thema noch mal ne Frage.

Folgender Sachverhalt:

Ich sende eine Formular per POST über den Submit Button an ein PHP Dokument ab:

Code: Alles auswählen

<form id="ticket" name="ticket" action="http://localhost/praktikum2de/edit.php" method="post">
<fieldset>
         <p>
         <label>Startbundesland: </label>
         <select id="blandstart" name="blandstart" onchange="change(this)"><option>Wert1</option></select>
         </p>
         <p>
         <label>Zielbundesland: </label>
         <select id="blandziel" name="blandziel" onchange="change(this)"><option>Wert2</option>
         </select></p>
</fieldset>
         <p><input type="submit" /></p>
</form>
Alles bestens und der Firebug zeigt mir die beiden Parameter aus den Select Feldern im POST an.

Sende ich das gleiche Formular an ein Cherrypy Script so bleibt der POST Bereich im Firebug leer:

Code: Alles auswählen

<form id="ticket" name="ticket" action="/doit" method="post">
<fieldset>
         <p>
         <label>Startbundesland: </label>
         <select id="blandstart" name="blandstart" onchange="change(this)"><option>Wert1</option></select>
         </p>
         <p>
         <label>Zielbundesland: </label>
         <select id="blandziel" name="blandziel" onchange="change(this)"><option>Wert2</option>
         </select></p>
			</fieldset>
         <p><input type="submit" /></p>
</form>
Den Response vom Cherrypy Script kommt zurück aber ich kann halt die Parameter aus dem POST nicht nutzen.

Woran kann das liegen, dass der POST Bereich des Requests leer bleibt?
Das läuft bei beiden Request ja alles vor dem PHP bzw. Cherrypy Script ab.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

slapshot1979 hat geschrieben:Den Response vom Cherrypy Script kommt zurück aber ich kann halt die Parameter aus dem POST nicht nutzen.
Hallo slapshot1979!

Da muss irgendwo noch ein Fehler versteckt sein.

Hier sind drei funktionierende POST-Beispiele mit CherryPy:
- http://halvar.at/python/cherrypy_cheeta ... ttp-header
- http://www.python-forum.de/post-102447.html#102447
- http://www.python-forum.de/post-102555.html#102555

Ich weiß nicht was in deinem Programm schief läuft. Aber wenn CherryPy die Parameter nicht bekommt, dann kannst du im CherryPy natürlich nichts damit anfangen. Ich denke, dass die Parameter vom Browser nicht versendet werden. Spätestens das Abhorchen des TCP/IP-Verkehrs vom Browser zum Server würde Klarheit schaffen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Oh mein Gott. Vielen Danke für die Links. Die haben mich auf die richtige Fährte gebracht. Da wäre ich wahrscheinlich nie drauf gekommen.

Bei POST muss der Actionhandler mit einem / abgeschlossen werden:

Code: Alles auswählen

<form id="ticket" name="ticket" action="/doit/" method="post">
Bei GET scheint es egal zu sein, ob der abschliessende / da steht oder nicht:

Code: Alles auswählen

<form id="ticket" name="ticket" action="/doit" method="get">
<form id="ticket" name="ticket" action="/doit/" method="get">
Gruß Andre
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Also *wenn* dem so ist, dann ist da entweder bei CherryPy oder deiner AJAX-Lib was nicht in Ordnung, wage ich mal zu behaupten. Mit und ohne Slash am Ende sind es ja zwei unterschiedliche URLs!
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Tja keine Ahnung warum das so ist, ich bin hier nur der Neuling. :D

Gemountet habe ich es im Python Script mit:

Code: Alles auswählen

cherrypy.tree.mount(doit_cl(), "/doit")
Edit:
Die AJAX lib kommt von prototype.js
Zuletzt geändert von slapshot1979 am Donnerstag 19. Juni 2008, 17:40, insgesamt 1-mal geändert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

slapshot1979 hat geschrieben:Gemountet habe ich es im Python Script mit:

Code: Alles auswählen

cherrypy.tree.mount(doit_cl(), "/doit")
Hallo!

Alles was mir dazu einfällt: Die einzige Methode, die bei so etwas Schwierigkeiten machen kann ist die ``index``-Methode. Und auch nur dann, wenn in der Konfiguration die Einstellung "tools.trailing_slash.on = True" gesetzt ist. Die Index-Methode ist ja auch nicht dafür gedacht, per Ajax aufgerufen zu werden. Die Index-Methode gibt das "Standardobjekt" des virtuellen, gemounteten Ordners zurück.

Bei der oben genannten Einstellung, wird immer dann, wenn ein Aufruf eines gemounteten Ordners, ohne angehängtem Slash ankommt, ein REDIRECT zur gleichen URL, aber diesmal mit Slash ausgelöst. Damit so etwas standardmäßig nicht passiert, ist die Einstellung "tools.trailing_slash.on" normalerweise auch nicht eingeschaltet.

Ich würde für Ajax andere Methodennamen verwenden.

...

Ich habe die weiter oben genannten Beispiele so umgeschrieben, dass jeweils die index-Methode die AJAX-Requests beantwortet. Dann habe ich es jeweils mit und ohne die Einstellung der Einstellung "tools.trailing_slash.on" und auch mit True und False als Werte für diese Einstellung getestet. --> Alles funktionierte.

Also was ich weiter oben über die index-Methode geschrieben habe, hat keine Auswirkung auf meine Tests. OK, ich habe es jetzt nur mit dem Firefox 2 getestet. Es kann natürlich sein, dass der IE anders reagiert.

...

Ich habe die Tests mit dem IE wiederholt. --> Alles funktioniert.

Mehr kann ich nicht machen. Mir fällt sonst nichts mehr ein.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Ahhhhh!

Ich habe es gefunden! :-)

Das tritt nicht auf, wenn man direkt mit dem virtuellen Root-Ordner arbeitet. Es tritt nur dann auf, wenn man einen virtuellen Unterordner mit ``cherrypy.tree.mount`` erstellt und dann noch die Einstellung ``tools.trailing_slash.on = True`` gesetzt hat.

Also muss man nur darafu achten, dass für diesen virtuellen Ordner die Einstellung ``tools.trailing_slash.on = False`` gesetzt wird. Dann braucht man nichts am Programm ändern und kann die index-Methode weiter benutzen (wenn man möchte).

Ob CherryPy diesen Fehler auslöst, erkennst du im CherryPy-Log. Dann wird an den Browser der Status "303" statt "200" zurück geschickt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
slapshot1979
User
Beiträge: 9
Registriert: Montag 16. Juni 2008, 12:04

Wenn ich "tools.trailing_slash.on = False" in meine config eintarge, klappt es auch bei mir ohne das / am Ende.

Wie ich gelesen habe ich das trailing.slash standardmässig auf True gesetzt:

Code: Alles auswählen

tools.trailing_slash.on = True
tools.trailing_slash.missing = True
tools.trailing_slash.extra = False

Also wäre es am Besten und korrektesten, wenn ich von den Index Methoden weggehe oder?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

slapshot1979 hat geschrieben:Also wäre es am Besten und korrektesten, wenn ich von den Index Methoden weggehe oder?
Hallo slapshot1979!

Ja genau. Einfach einen anderen Methodennamen verwenden und schon läuft alles. :D

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten