Python 3 Tornado 文件主体及头部

0 投票
1 回答
728 浏览
提问于 2025-04-18 12:11

我正在用Python3和Tornado写一个简单的应用,服务器用Tornado,客户端用requests。现在我在'self.request.body'中得到了些头信息,但我不知道怎么处理它。比如,对于文件'blahblahblah',我得到了:

--cb5f6ba84bdf42d382dfd3204f6307c7\r\nContent-Disposition: form-data; name="file"; filename="1.bin"\r\n\r\nblahblahblah\n\r\n--cb5f6ba84bdf42d382dfd3204f6307c7--\r\n

文件是通过

f = {'file': open(FILE, 'rb')}
requests.post(URL_UPLOAD, files=f)

发送的,接收是通过

class UploadHandler(tornado.web.RequestHandler):
    def post(self, filename):
        with open(Dir + filename, 'wb') as f:
            f.write(self.request.body)

我的完整代码可以在这里查看。

当我用curl命令发送文件,命令是curl -X POST -d $(cat ./1.bin) http://localhost:8080/upload/1.bin,我能收到正确的文件,但没有\n。

我一定是漏掉了什么。请问有人能帮我解决这个问题吗?谢谢。

1 个回答

0

上传文件有两种方式:一种是直接把文件作为请求的主体发送(通常用HTTP PUT方法,但不一定),另一种是使用一个多部分的包装(通常用HTTP POST方法)。如果你是通过HTML表单上传文件,通常会使用多部分包装。你提供的请求示例是用的多部分包装,而curl的示例则不是;所以你的服务器不期待这个包装。

如果要使用多部分包装:在requests中,像你这里做的那样传入 files=。如果使用curl,可以参考这个答案:使用curl上传带文件的POST数据。在服务器端,使用 self.request.files 而不是 self.request.bodyhttp://www.tornadoweb.org/en/stable/httpserver.html#tornado.httpserver.HTTPRequest.files

如果想使用多部分包装,可以用 data=open(FILE, 'rb').read() 从requests中读取文件,其他两个部分保持不变。

在服务器上同时支持这两种方式也是可以的:当 self.request.headers['Content-Type'] == 'multipart/form-data' 时使用 self.request.files,否则使用 self.request.body

撰写回答