Python 3 Tornado 文件主体及头部
我正在用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 个回答
上传文件有两种方式:一种是直接把文件作为请求的主体发送(通常用HTTP PUT方法,但不一定),另一种是使用一个多部分的包装(通常用HTTP POST方法)。如果你是通过HTML表单上传文件,通常会使用多部分包装。你提供的请求示例是用的多部分包装,而curl的示例则不是;所以你的服务器不期待这个包装。
如果要使用多部分包装:在requests中,像你这里做的那样传入 files=
。如果使用curl,可以参考这个答案:使用curl上传带文件的POST数据。在服务器端,使用 self.request.files
而不是 self.request.body
:http://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
。