问题描述
我想使用 Twisted Web Client 发送带有多个参数的 POST 请求:
- 图像:图像
- Metadata : 带有元数据的 json 文档 我需要使用纯 Twisted,而不需要像 Treq 和 requests 这样的外部库。
有人知道如何改变身体来达到这个目标吗?
from __future__ import print_function
from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers
from bytesprod import BytesProducer
agent = Agent(reactor)
body = BytesProducer(b"hello,world")
d = agent.request(
b'POST',b'http://httpbin.org/post',Headers({'User-Agent': ['Twisted Web Client Example'],'Content-Type': ['text/x-greeting']}),body)
def cbResponse(ignored):
print('Response received')
d.addCallback(cbResponse)
def cbShutdown(ignored):
reactor.stop()
d.addBoth(cbShutdown)
reactor.run()
解决方法
您需要指定参数的编码方式。如果你想像浏览器表单一样提交它们,你需要对数据进行 application/x-www-form-urlencoded 或 multipart/form-data 编码。前者通常用于短数据 - 由于您的参数是“图像”,它可能并不短。所以你应该 multipart/form-data 数据。
一旦有了,您只需在请求头中声明并在正文中包含编码数据。
例如
body = multipart_form_encoded_body_producer(your_form_fields))
d = agent.request(
b'POST',b'http://httpbin.org/post',Headers({'User-Agent': ['Twisted Web Client Example'],'Content-Type': ['multipart/form-data']}),body)
方便的是,treq 提供了 a multipart/form-data encoder
所以 multipart_form_encoded_body_producer(...)
可能看起来像:
MultiPartProducer([
("image",image_data),("metadata",some_metadata),...
])
您提到不能使用 Treq。你没有提到为什么。我建议使用 Treq 或至少找到另一个可以为您进行编码的库。如果由于某些不合理的原因不能这样做,则必须自己实现 multipart/form-data 编码。它是 reasonably well documented,当然,您还可以将多种实现用作参考和互操作性测试工具。