2013-07-17 5 views
6

Ich bin ein Neuling für Python (mit v3.3) und Web-Programmierung und ich habe die ganze Nacht mit einem Problem gekämpft. Ich bin eine POST-Aufruf zu meinem Server Ausgabe und einige Daten zu senden, wie folgt:Wie greife ich auf die Daten zu, die mit BaseHTTPRequestHandler an meinen Server gesendet werden?

DATA = {"listName":"Test list","listDesc":"A test list with test stuff in it.","refreshMode":"Replace","DBKey":"1","UserDisplaySeq":"1"} 
DATA = json.dumps(DATA) 
METHOD = "POST" 
DATA = DATA.encode("utf-8") 
params = "account_id=acct 2" 
try: 
    URL = "http://localhost:8080/lists?" + quote_plus(params) 
    request = urllib.request.Request(url=URL,data=DATA,method=METHOD) 
    response = urllib.request.urlopen(request) 
... 

ich auch einen Request-Handler haben wie folgt codiert (es gibt viele print-Anweisungen in hier für Debug-Zwecke):

class MyHandler(BaseHTTPRequestHandler): 
... 
def do_POST(self): 
    length = int(self.headers['Content-Length']) 
    print("HEADERS: ", self.headers) 
    print (str(length)) 
    print(self.rfile) 
    post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8')) 
    print(post_data) 

Dies druckt das folgende Ergebnis an die Konsole:

Starting thread 
started httpserver... 
HEADERS: Accept-Encoding: identity 
User-Agent: Python-urllib/3.3 
Content-Length: 138 
Content-Type: application/x-www-form-urlencoded 
Host: localhost:8080 
Connection: close 


138 
<_io.BufferedReader name=404> 
{} 

Meine Fragen:
1) auf dem Server (do_POST), wie kann ich auf die Daten zugreifen, die ich mit meiner Anfrage gesendet habe (z. { "Listenname": "Testliste", "LISTDESC": "Ein Test ...)

2) Ist meine Anfrage auch die Daten in erster Linie das Senden

3) Gibt es einen Ort? wo dies in Anfänger-Auftragsbedingungen dokumentiert ist?

+0

Sie können feststellen, dass die Verwendung eines Web-Frameworks wie Flask oder Bottle diese Dinge viel einfacher machen wird. – Blender

+0

@Blender - Danke für den Hinweis. Ich habe es mit Bottle versucht, aber es schien wirklich darauf ausgerichtet zu sein, HTML zu verwenden, was wir in unserem Fall nicht verwenden. Wir schreiben eine RESTful-Anwendung, um die Arbeit auf mehreren Servern auszubalancieren und es hat wirklich keine Browser-Komponente. Wie fast alle diese Dinge, fand ich auch die Dokumentation von Bottle großartig, wenn du deine Sachen bereits kennst, aber wirklich hart für Anfänger, die keinen Hintergrund in Web-Konzepten haben. – Ben

Antwort

5

dies ein Versuch geben. ich habe es von an answer to another question

def do_POST(self): 
    ctype, pdict = cgi.parse_header(self.headers.getheader('content-type')) 
    if ctype == 'multipart/form-data': 
     postvars = cgi.parse_multipart(self.rfile, pdict) 
    elif ctype == 'application/x-www-form-urlencoded': 
     length = int(self.headers.getheader('content-length')) 
     postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1) 
    else: 
     postvars = {} 

    print(postvars.get("listName", "didn't find it")) 
+0

Danke, Nate, das war wirklich hilfreich. Ich habe am Ende die cgi.parse_qs durch urllib.parse.parse_qs ersetzt und es scheint zu funktionieren. Ich bin zu müde, um herauszufinden, warum gerade jetzt, aber der Trick war die keep_blank_values ​​= 1 Flagge. – Ben

4

1) in dem Server (do_POST), wie kann ich die Daten zugreifen, ich glaube, ich m Senden mit meiner Anfrage (zB {"listName": "Testliste", "listDesc": "Ein Test ...)?

können Sie auf die Daten zugreifen nur von:

Druck self.rfile.read (Länge).

nach sicherstellen, dass dies funktioniert. Sie können andere Analysen durchführen. Ich schlage vor, benutze Simplejson, um die JSON-Zeichenfolge zu dekodieren. urllib.parse.parse_qs scheint unnötig.

2) Gibt meine Anfrage überhaupt die Daten an die erste Stelle?

the code looks fine. to make sure it works, just try: 

    curl -d "asdf" http://yourhost:yourport 

to see if the server have same response. 
so you can know whether the server side or client side goes wrong. 

3) Gibt es einen Ort, an dem dies in für Anfänger zugänglichen Begriffen dokumentiert ist?

the official document is always a good choice: 
http://docs.python.org/2/library/basehttpserver.html 
+0

Aus irgendeinem Grund funktioniert der Ausdruck self.rfile.read (Länge) nicht für mich - es verursacht nur die Python-Shell (IDLE in Win7) zu hängen. Auch das Dokument, auf das Sie verweisen, ist ein großartiger Fall. Ich habe davon gelesen, dass ich auf das Attribut 'rfile' zugreifen muss, aber es sagt nichts über den Parameter keep_blank_values ​​aus. Ich vermute, es gibt einige Literatur im Internet, die helfen könnten, aber da es so viel gibt, ist es schwierig, den richtigen Gegenstand zu finden. Wie auch immer, danke für deine Hilfe! – Ben