2013-07-17 24 views
6

Tôi là người mới dùng Python (sử dụng v3.3) và lập trình web và tôi đã phải vật lộn với một vấn đề cả đêm. Tôi đang phát hành một cuộc gọi POST để máy chủ của tôi và gửi nó một số dữ liệu như sau:Làm cách nào để truy cập dữ liệu được gửi đến máy chủ của tôi bằng 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) 
... 

Tôi cũng có một bộ xử lý yêu cầu mã hóa như sau (có rất nhiều báo cáo in ở đây cho mục đích gỡ lỗi):

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) 

này in kết quả sau vào giao diện điều khiển:

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

tôi câu hỏi:
1) Trong máy chủ (do_POST), làm cách nào để truy cập dữ liệu tôi cho là tôi đang gửi cùng với yêu cầu của mình (tức là { "Listname": "danh sách thử nghiệm", "listDesc": "Một thử nghiệm ...)

2) là yêu cầu của tôi thậm chí còn gửi dữ liệu ở nơi đầu tiên

3) Có một nơi? nơi này là tài liệu về người mới có thể truy cập?

+0

Bạn có thể thấy rằng việc sử dụng khung web như Flask hoặc Bottle sẽ làm cho công cụ này trở nên dễ dàng hơn nhiều. – Blender

+0

@Blender - Cảm ơn lời khuyên. Tôi đã thử sử dụng Bottle nhưng nó dường như thực sự hướng đến việc sử dụng HTML, trong trường hợp của chúng tôi, chúng tôi không sử dụng. Chúng tôi đang viết một ứng dụng RESTful để cân bằng công việc trên nhiều máy chủ và nó thực sự không có một thành phần trình duyệt. Giống như hầu như tất cả những điều này, tôi cũng tìm thấy tài liệu của Bottle là tuyệt vời nếu bạn đã biết công cụ của bạn nhưng thực sự khó khăn cho người mới bắt đầu không có một nền tảng trong các khái niệm web. – Ben

Trả lời

5

này cung cấp cho một thử. tôi đã đánh cắp nó từ 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

Cảm ơn, Nate, điều này thực sự hữu ích. Tôi đã thay thế cgi.parse_qs bằng urllib.parse.parse_qs và nó có vẻ hoạt động. Tôi quá mệt mỏi để tìm ra lý do tại sao ngay bây giờ nhưng thủ thuật là keep_blank_values ​​= 1 flag. – Ben

4

1) trong máy chủ (do_POST), làm thế nào để truy cập dữ liệu tôi nghĩ tôi m gửi cùng với yêu cầu của tôi (ví dụ: {"listName": "Danh sách kiểm tra", "listDesc": "Kiểm tra ...)?

bạn có thể truy cập dữ liệu chỉ bằng:

print self.rfile.read (length).

sau khi đảm bảo điều này đang hoạt động. bạn có thể làm công việc phân tích cú pháp khác. Tôi đề nghị sử dụng simplejson để giải mã chuỗi json. urllib.parse.parse_qs có vẻ không cần thiết.

2) Yêu cầu của tôi thậm chí có gửi dữ liệu ngay từ đầu không?

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) Có nơi nào được ghi lại trong các thuật ngữ có thể truy cập mới không?

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

Vì một số lý do, bản in self.rfile.read (chiều dài) không hoạt động đối với tôi - nó chỉ làm cho vỏ python (IDLE trong Win7) bị treo. Ngoài ra, tài liệu bạn trỏ đến là một trường hợp tuyệt vời tại điểm. Tôi đã nhận từ nó mà tôi cần phải truy cập thuộc tính 'rfile' nhưng nó không nói bất cứ điều gì về tham số keep_blank_values. Tôi nghi ngờ có một số tài liệu trên web có thể giúp đỡ nhưng, bởi vì có quá nhiều thứ ở đó, việc tìm kiếm đúng mục là khó khăn. Nhưng dù sao, cảm ơn sự giúp đỡ của bạn! – Ben

Các vấn đề liên quan