2015-10-01 7 views
6

कोड का निम्नलिखित भाग पायथन 2.7 और पायथन 3.x में चलाने में सक्षम होना चाहिए।cgi.FieldStorage का उपयोग कर पार्स मल्टीपार्ट/फॉर्म-डेटा; कोई भी चाबियाँ

from __future__ import unicode_literals 
from __future__ import print_function 

import cgi 
try: 
    from StringIO import StringIO as IO 
except ImportError: 
    from io import BytesIO as IO 

body = """ 
--spam 
Content-Disposition: form-data; name="param1"; filename=blob 
Content-Type: binary/octet-stream 

value1 
--spam-- 
""" 

parsed = cgi.FieldStorage(
    IO(body.encode('utf-8')), 
    headers={'content-type': 'multipart/form-data; boundary=spam'}, 
    environ={'REQUEST_METHOD': 'POST'}) 

print([key for key in parsed]) 

अजगर 2.7 में यह ठीक चलाता है और यह ['param1'] आउटपुट। पाइथन 3.4 में हालांकि, यह [None] आउटपुट करता है।

मुझे पाइथन 3 में उपयोग करने योग्य परिणाम प्राप्त करने के लिए FieldStorage नहीं मिल सकता है। मुझे कुछ आंतरिक रूप से बदला गया है और अब मैं इसे गलत उपयोग कर रहा हूं। हालांकि मुझे यह पता लगाना प्रतीत नहीं होता है कि क्या। किसी भी मदद की सराहना की है।

उत्तर

3

इन परिवर्तनों को अपनी स्क्रिप्ट काम हूबहू कर देगा

: दोनों पायथन 2.7.x और 3.4.x में (मैं cgi.FieldStorage() के लिए इन रूपों का उपयोग होगा: अजगर 2.7.x: FS27, पायथन 3.4.x: FS34)

- जबकि FS27 सही ढंग से सीमा से पहले न्यू लाइन संभालती है, कि नहीं FS34 के मामले में तो समाधान अपने सीमा (spam) सीधे साथ शुरू करने के लिए है।

body = """--spam 
Content-Disposition: form-data; name="param1"; filename=blob 
Content-type: binary/octet-stream 

value1 
--spam-- 
""" 

- cgi.py से हवाला देते हुएsource (FS34 के परिभाषा टिप्पणी में):

तर्क, सभी वैकल्पिक:

fp: फ़ाइल सूचक; डिफ़ॉल्ट: sys.stdin.buffer (इस्तेमाल नहीं किया जब अनुरोध विधि प्राप्त है)

 Can be : 
     1. a TextIOWrapper object 
     2. an object whose read() and readline() methods return bytes 

ग्रे भाग में FS27 परिभाषा मौजूद नहीं है, इसलिए, FS27 और के बीच मतभेद का सबसे एफएस 34स्ट्रिंग्स (एफएस 27) और बाइनरी स्ट्रीम (एफएस 34) के संचालन में झूठ बोल रहा है।

इस संदर्भ में, FS34 आसानी से पार्स किए गए ऑब्जेक्ट के अर्थशास्त्र को गड़बड़ कर सकता है, जब तक कि इसे सही ढंग से संभालने के तरीके पर उचित निर्देश दिए जाएं। जाहिर है, headers शब्दकोश प्रविष्टि 'content-type': 'multipart/form-data; boundary=spam' पर्याप्त नहीं है; आपको संदेश की लंबाई की जानकारी प्रदान करनी है।

आप इस लक्ष्य को हासिल कर सकते हैं, प्रभावी रूप से, headers में एक दूसरी प्रविष्टि जोड़कर:

headers={'content-type': 'multipart/form-data; boundary=spam;', 
'content-length': len(body)} 

जहां content-lengthकुंजी के लिए मूल्यbody लंबाई है (प्रारंभ/समाप्ति सीमाओं सहित)।


इन संशोधनों, संयुक्त, वांछित परिणाम के लिए नेतृत्व:

$ python script.py 
['param1'] 
$ python3 script.py 
['param1'] 

के रूप में सबूत अवधारणा-का-, इन दोनों FS27 और से parsed वस्तुओं लौटा दिए जाते हैं एफएस 34:

... 
print(parsed) 
... 

पैदावार:

FieldStorage(None, None, [FieldStorage('param1', 'blob', 'value1')]) 

FS27, और

FieldStorage(None, None, [FieldStorage('param1', 'blob', b'value1')]) 

के लिए FS34 के लिए।

0

में दोनों अजगर 2.7 और अजगर 3.5 (किसी कारण से अजगर 3.4 में काम नहीं कर रहा), वांछित आउटपुट प्रतिक्रिया शरीर के लिए Content-Length जोड़कर दिया जाता है:

body = """ 
--spam 
Content-Disposition: form-data; name="param1"; filename=blob 
Content-Length: 6 
Content-Type: binary/octet-stream 

value1 
--spam-- 
""" 
संबंधित मुद्दे