使用 cgi.FieldStorage 解析 multipart/form-data; None 键
Parse multipart/form-data using cgi.FieldStorage; None keys
下面这段代码应该可以运行 in Python 2.7 和 Python 3.x.
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])
在 Python 2.7 中 运行 没问题,它输出 ['param1']
。然而,在 Python 3.4 中,它输出 [None]
.
我无法 FieldStorage
在 Python 中获得可用的结果 3. 我怀疑内部发生了一些变化,我现在使用错误。但是我似乎无法弄清楚是什么。感谢任何帮助。
在 Python 2.7 和 Python 3.5 中(由于某些原因在 Python 3.4 中不起作用),通过将 Content-Length
添加到响应中返回所需的输出正文:
body = """
--spam
Content-Disposition: form-data; name="param1"; filename=blob
Content-Length: 6
Content-Type: binary/octet-stream
value1
--spam--
"""
这些更改将使您的脚本在 Python 2.7.x 和 3.4.x:
中相同地工作
(我将这些缩写用于 cgi.FieldStorage()
:Python 2.7.x:FS27,Python 3.4.x: FS34)
1 - 虽然 FS27 正确处理边界前的换行符,但 FS34[ 并非如此=81=] 所以解决方案是直接从你的边界(spam
)开始。
body = """--spam
Content-Disposition: form-data; name="param1"; filename=blob
Content-type: binary/octet-stream
value1
--spam--
"""
2 - 引用自 cgi.py source (在 FS34 的 定义注释中):
Arguments, all optional:
fp : file pointer; default: sys.stdin.buffer
(not used when the request method is GET)
Can be :
1. a TextIOWrapper object
2. an object whose read() and readline() methods return bytes
FS27定义中没有灰色部分,因此,FS27和FS34之间的大部分差异 在于 strings(FS27) 和 binary streams(FS34).
的处理
在这种情况下,FS34 很容易混淆已解析对象的语义,除非给出正确的指示以正确处理它。显然,headers
字典条目 'content-type': 'multipart/form-data; boundary=spam'
是不足够的;您必须提供消息长度信息。
您可以通过在 headers
中添加第二个条目 有效地 实现此目的:
headers={'content-type': 'multipart/form-data; boundary=spam;',
'content-length': len(body)}
其中 content-length
key 的 value 是 body
长度(包括 start/end边界)。
这些修改结合起来会产生预期的结果:
$ python script.py
['param1']
$ python3 script.py
['param1']
作为概念验证,这些是 FS27 和 返回的 parsed
对象]FS34:
...
print(parsed)
...
产量:
FieldStorage(None, None, [FieldStorage('param1', 'blob', 'value1')])
对于 FS27 和
FieldStorage(None, None, [FieldStorage('param1', 'blob', b'value1')])
对于 FS34。
下面这段代码应该可以运行 in Python 2.7 和 Python 3.x.
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])
在 Python 2.7 中 运行 没问题,它输出 ['param1']
。然而,在 Python 3.4 中,它输出 [None]
.
我无法 FieldStorage
在 Python 中获得可用的结果 3. 我怀疑内部发生了一些变化,我现在使用错误。但是我似乎无法弄清楚是什么。感谢任何帮助。
在 Python 2.7 和 Python 3.5 中(由于某些原因在 Python 3.4 中不起作用),通过将 Content-Length
添加到响应中返回所需的输出正文:
body = """
--spam
Content-Disposition: form-data; name="param1"; filename=blob
Content-Length: 6
Content-Type: binary/octet-stream
value1
--spam--
"""
这些更改将使您的脚本在 Python 2.7.x 和 3.4.x:
中相同地工作(我将这些缩写用于 cgi.FieldStorage()
:Python 2.7.x:FS27,Python 3.4.x: FS34)
1 - 虽然 FS27 正确处理边界前的换行符,但 FS34[ 并非如此=81=] 所以解决方案是直接从你的边界(spam
)开始。
body = """--spam
Content-Disposition: form-data; name="param1"; filename=blob
Content-type: binary/octet-stream
value1
--spam--
"""
2 - 引用自 cgi.py source (在 FS34 的 定义注释中):
Arguments, all optional:
fp : file pointer; default: sys.stdin.buffer (not used when the request method is GET)
Can be : 1. a TextIOWrapper object 2. an object whose read() and readline() methods return bytes
FS27定义中没有灰色部分,因此,FS27和FS34之间的大部分差异 在于 strings(FS27) 和 binary streams(FS34).
的处理在这种情况下,FS34 很容易混淆已解析对象的语义,除非给出正确的指示以正确处理它。显然,headers
字典条目 'content-type': 'multipart/form-data; boundary=spam'
是不足够的;您必须提供消息长度信息。
您可以通过在 headers
中添加第二个条目 有效地 实现此目的:
headers={'content-type': 'multipart/form-data; boundary=spam;',
'content-length': len(body)}
其中 content-length
key 的 value 是 body
长度(包括 start/end边界)。
这些修改结合起来会产生预期的结果:
$ python script.py
['param1']
$ python3 script.py
['param1']
作为概念验证,这些是 FS27 和 返回的 parsed
对象]FS34:
...
print(parsed)
...
产量:
FieldStorage(None, None, [FieldStorage('param1', 'blob', 'value1')])
对于 FS27 和
FieldStorage(None, None, [FieldStorage('param1', 'blob', b'value1')])
对于 FS34。