如何在twisted.web中实现不糟糕的文件上传?

9 投票
2 回答
5369 浏览
提问于 2025-04-16 01:26

我搜索了很久,但就是找不到一个合理的方法来上传文件到我的twisted.web应用。

现在,上传文件到某个资源后,会得到一个request.args['file']变量,这个变量是一个包含文件内容的列表。我找不到获取文件信息的方法,比如:文件类型、文件名、文件大小(除了通过计算args['file'][]中字符串的长度来获取)等等。

我听说twisted.web2在文件上传方面做得更好。不过我不知道它到底好多少,也不知道如何在twisted.web应用中使用twisted.web2来处理文件上传。

有没有什么建议?这让我很烦恼——哦,我查看了请求头,但没有找到什么有用的信息。我该如何在Twisted中获取更多关于文件上传的元信息呢?

另外,

我该如何从请求对象中获取最基本的HTTP请求?这可能吗?

2 个回答

3

我按照这里描述的方法做的:上传的解决方案。这个解决方案使用了 cgi.FieldStorage 来解析数据。

另外:为了进行解析,你需要用 request.content,而不是 request[args]。如你所见,结果和 web2 中的 request.files 几乎是一样的。

5

这是一个老问题,不过在StackOverflow上快速搜索了一下,没有找到类似的问题和答案,所以这里给大家简单举个例子,讲讲怎么用 twisted.web2 来上传文件。

这里有个隐藏的表单变量 file_foo,它和文件上传的变量名字是一样的,目的是为了展示Twisted是怎么把这些变量分开的:

<form action="/upload?a=1&b=2&b=3" enctype="multipart/form-data"
        method="post">
    <input type="hidden" name="foo" value="bar">
    <input type="hidden" name="file_foo" value="not a file">
    file_foo: <input type="file" name="file_foo"><br/>
    file_foo: <input type="file" name="file_foo"><br/>
    file_bar: <input type="file" name="file_bar"><br/>
    <input type="submit" value="submit">
</form>

在你的 Resource.render() 方法中,下面是你可以用来访问表单变量的方式:

def render(self, ctx):
    request = iweb.IRequest(ctx)
    for key, vals in request.args.iteritems():
        for val in vals:
            print key, val

    print 'file uploads ----------------'
    for key, records in request.files.iteritems():
        print key
        for record in records:
            name, mime, stream = record
            data = stream.read()
            print '   %s %s %s %r' % (name, mime, stream, data)

    return http.Response(stream='upload complete.')

输出结果:

         a: 1
         b: 2 3
       foo: bar
  file_foo: not a file

file_bar
   bar.txt MimeType('text', 'plain', {}) <open file '<fdopen>', mode 'w+b' at 0x2158a50> 'bar data.\n\n'
file_foo
   foo.txt MimeType('text', 'plain', {}) <open file '<fdopen>', mode 'w+b' at 0x2158930> 'foo data.\n\n'
   foo.txt MimeType('text', 'plain', {}) <open file '<fdopen>', mode 'w+b' at 0x21589c0> 'foo data.\n\n'

撰写回答