2013-07-17 20 views
6

Ben Python (v3.3 kullanarak) ve web programlaması için bir acemi yaşıyorum ve bütün gece bir sorun ile mücadele ediyorum. Benim sunucuya bir POST çağrısı veren ve aşağıdaki gibi bunu bazı verileri yolluyorum şu şekildedir:SunHTTPRequestHandler kullanarak sunucuma gönderilen verilere nasıl erişirim?

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

Ben de kodlanmış bir istek işleyicisi var (Hata ayıklama amacıyla burada baskı tabloların yeri vardır):

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) 

Bu konsola aşağıdaki sonucu yazdırır:

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

Sorularım:
1) sunucuya (do_POST), nasıl I do isteğimle gönderdiğimi düşündüğüm verilere erişiyorum (ör. { "ListName": "Test listesi", "listDesc":? "Bir test ...)

2) bile ilk etapta veri göndermeyi ricam var

3) bir yer var mı? nerede bu acemi erişilebilir açısından belgelenmiştir?

+0

Flask veya Bottle gibi bir web çerçevesi kullanmanın bu işi daha kolay hale getirdiğini görebilirsiniz. – Blender

+0

@Blender - Öneri için teşekkürler. Bottle'ı kullanmayı denedim, ancak gerçekten de HTML'yi kullanmaya yönelik görünüyordu. Çalışmayı birden çok sunucuda dengelemek için RESTful bir uygulama yazıyoruz ve gerçekten bir tarayıcı bileşenine sahip değiliz. Bu şeylerin hemen hemen hepsinde olduğu gibi, şişe dokümantasyonunda bir arka plana sahip olmayan yeni başlayanlar için gerçekten zor olan bir şey olsa da, Şişe dokümantasyonunu harika buldum. – Ben

cevap

5

Bu deneyin. sunucuda (do_POST) olarak 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

Teşekkürler Nate, bu gerçekten yardımcı oldu. Ben cgi.parse_qs yerine urllib.parse.parse_qs ile bitti ve işe görünüyor. Şu an nedenini bulmaktan çok yoruldum ama hile, keep_blank_values ​​= 1 bayrağıydı. – Ben

4

1) çaldı, ben verilere erişmek nasıl ben sanıyorlar m isteğimle gönderme (yani {"listName": "Test listesi", "listDesc": "Bir test ...)?

baskı self.rfile.read (uzunluk):

sadece tarafından verilerine erişebilir. Bunun çalıştığından emin olduktan sonra

. başka ayrıştırma işi yapabilirsin. Json dizesini çözmek için simplejson kullanmasını öneriyorum. urllib.parse.parse_qs gereksiz görünüyor.

2) İsteğim, verileri ilk etapta gönderiyor mu?

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) Bu acemi erişilebilir açısından belgelenmiştir bir yer var mı?

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

Herhangi bir nedenden ötürü, print self.rfile.read (length) benim için çalışmıyor - python kabuğunun (Win7'deki IDLE) asılmasına neden oluyor. Ayrıca, işaret ettiğiniz belge, tam anlamıyla mükemmel bir durumdur. Ben 'rfile' özniteliğine erişmek için ihtiyacım var ama keep_blank_values ​​parametresi hakkında bir şey söylemiyor. Web üzerinde, yardımcı olabilecek bazı literatür olduğunu sanıyorum, ama orada çok fazla şey olduğu için, doğru öğeyi bulmak zor. Her neyse, yardımın için teşekkürler! – Ben

İlgili konular