python: 解析带文件上传和其他参数的HTTP POST请求

5 投票
3 回答
3169 浏览
提问于 2025-04-15 15:00

这个任务很简单:在服务器端(用Python)接收一个HTTP POST请求,这个请求里包含一个上传的文件和一些其他的表单参数。

我想实现一个上传进度指示器,因此我需要能够逐块读取文件内容。

我找到的所有方法都是基于cgi.FieldStorage的,但这个方法似乎只能让我一次性获取整个文件(在内存中,这本身就很糟糕)。有人建议重新定义FieldStorage.make_file方法,但这似乎会破坏cgi的实现(真奇怪...)。

目前,我能够逐块读取整个wsgi输入,并将其写入文件系统,结果如下:

-----------------------------9514143097616
Content-Disposition: form-data; name="myfile"; filename="inbound_marketing_cartoon_ebook.pdf"
Content-Type: application/pdf

... 1.5 MB of PDF data

-----------------------------9514143097616
Content-Disposition: form-data; name="tid"

194
-----------------------------9514143097616--

有没有人知道有没有什么Python库可以可靠地解析这个东西?还是我应该手动处理?(我用的是Python 2.5)

谢谢。

3 个回答

0

你可以看看Django是怎么做的。他们有一个很不错的自定义文件上传处理程序的实现,这让你可以通过继承这些处理程序来实现一些功能,比如进度条等等。可以查看这份文档相关代码 - 即使你不打算使用Django,这些内容也一定能给你一些启发。

1

这听起来有点反直觉(而且我觉得这个模块的名字起得不好),但其实 email 很可能能满足你的需求。我自己没用过这个模块,但我的一个同事在一个邮件处理系统中用过;因为这些邮件本质上就是RFC 2822格式,所以 email 很可能能解析它们。

关于 email 的文档 看起来相当详细。

我直觉上觉得,你最终可能会把文件加载到内存中,而你对此表示过不满。

2

正如你所建议的,我会(而且之前也做过)重写一个叫做 make_file 的方法,这个方法属于一个叫做 FieldStorage 的对象。你只需要返回一个有 write 方法的对象,这个方法可以接收数据(可以是写入文件、内存或者其他地方),同时还可以记录接收到的数据量,以便你显示进度。

这样做的话,你还可以获取到文件的长度(客户端提供的)、文件名,以及它是以什么关键字上传的。

为什么这样做会让你觉得CGI的实现出现问题呢?

另外一个选择是在浏览器中使用闪存上传工具来跟踪进度(比如 YUI UploaderSWFUpload),完全不在服务器上进行进度跟踪。这样你就不需要一系列的AJAX请求来获取进度了。

撰写回答