2013-07-17 12 views
6

Jestem nowicjuszem w Pythonie (używając v3.3) i programowaniem w sieci i przez całą noc zmagałem się z problemem. Ja wydaniem wywołanie POST do mojego serwera i wysyłając mu pewne dane w następujący sposób:Jak uzyskać dostęp do danych wysłanych do mojego serwera za pomocą BaseHTTPRequestHandler?

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) 
... 

Mam też obsługi żądania kodowane następująco (istnieje wiele instrukcji print tu dla celów debugowania):

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) 

drukuje następujący wynik do konsoli:

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> 
{} 

moje pytania:
1) na serwerze (do_POST), jak mogę dostęp do danych, które myślę, że wysyłam z moją prośbą (tj. { "Listname": "lista Test", "listDesc": "Test ...)

2) Czy moja prośba nawet wysyłania danych w pierwszej kolejności

3) Czy jest jakieś miejsce? gdzie jest to udokumentowane w kategoriach początkujących inwalidzkim?

+0

Może się okazać, że korzystanie z frameworka WWW, takiego jak kolba lub butelka, znacznie ułatwi to zadanie. – Blender

+0

@Blender - Dzięki za poradę. Próbowałem używać Butelki, ale wydawało się, że naprawdę wykorzystałem HTML, który w naszym przypadku nie jest używany. Piszemy aplikację RESTful, aby zrównoważyć pracę na wielu serwerach i naprawdę nie ma ona składnika przeglądarki. Podobnie jak prawie wszystkie te rzeczy, znalazłem także dokumentację Butelki, aby była świetna, jeśli znałeś już swoje rzeczy, ale naprawdę ciężko dla początkujących, którzy nie mają tła w koncepcjach internetowych. – Ben

Odpowiedz

5

spróbuj tego. Wygrałem go od 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

Dzięki, Nate, to było naprawdę pomocne. Skończyło się na tym, że zamieniłem cgi.parse_qs na urllib.parse.parse_qs i wygląda na to, że działa. Jestem zbyt zmęczony, aby dowiedzieć się, dlaczego teraz, ale sztuczka była flagą keep_blank_values ​​= 1. – Ben

4

1) na serwerze (do_POST), w jaki sposób mogę uzyskać dostęp do danych myślę” m wysyłanie z moją prośbą (np. {"nazwa listy": "Lista testów", "listDesc": "Test ...)?

można uzyskać dostęp do danych tylko przez:

druku self.rfile.read (długość).

po upewnieniu się, że to działa. możesz wykonać inną pracę parse. Sugeruję użycie simplejson do dekodowania łańcucha json. urllib.parse.parse_qs wydaje się niepotrzebne.

2) Czy moje żądanie wysyła dane w pierwszej kolejności?

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) Czy istnieje miejsce, w którym jest to udokumentowane w przystępny sposób?

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

Z jakiegoś powodu drukowany plik self.rfile.read (długość) nie działa dla mnie - powoduje tylko zawieszenie powłoki Pythona (IDLE w Win7). Również dokument, o którym mówisz, jest świetnym przykładem. Zrobiłem od niego, że muszę uzyskać dostęp do atrybutu "rfile", ale nie mówi nic o parametrze keep_blank_values. Podejrzewam, że w sieci jest trochę literatury, która mogłaby pomóc, ale ponieważ jest tak dużo, znalezienie odpowiedniego przedmiotu jest trudne. W każdym razie, dzięki za pomoc! – Ben

Powiązane problemy