我们正在尝试用python(使用python-requests atm)编写一个脚本来向内容必须是MultipartFormData的站点发出POST请求。当我们手动执行此 POST 请求时(通过填写网站上的表格并发布),使用wireshark,出现了(短版):
Content-Type: multipart/form-data;
Content-Disposition: form-data; name="name"
Data (8 Bytes)
John Doe
当我们尝试使用 python-requests 库来实现相同的结果时,会发送以下信息:
Content-Type: application/x-pandoplugin
Content-Disposition: form-data; name="name"; filename="name"\r\n
Media type: application/x-pandoplugin (12 Bytes)
//and then in this piece is what we posted://
John Doe
奇怪的是,数据包的“一般类型”确实是多部分/表单数据,但是发送的单个项目(key = 'name', value='John Doe')的类型为 application/x-pandoplugin(随机我猜我的电脑上的应用程序)。
这是使用的代码:
response = s.post('http://url.com', files={'name': 'John Doe'})
有没有办法指定单个项目的内容类型而不是使用 headers 参数(它只会改变“整个”数据包的类型)?
我们认为服务器无法正确响应是因为它无法理解我们发送的内容类型。
小更新: 我认为多部分内容的不同部分现在与我在浏览器中执行 POST 时发送的部分相同,所以这很好。服务器实际上并没有做我用脚本发送的更改。唯一不同的是不同部分的顺序。
例如,这是我的浏览器发送的内容:
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: (text/plain)
Content-Disposition: form-data; name="file"; filename="ex.txt"\r\n
Content-Type: text/plain\r\n\r\n
Line-based text data: text/plain
lore ipsum blabbla
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:
Content-Disposition: form-data; name="seq"\r\n\r\n
Data (2 bytes)
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:
Content-Disposition: form-data; name="name"\r\n\r\n
Data (2 bytes)
这就是脚本(使用 python-requests)发送的内容:
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:
Content-Disposition: form-data; name="name"\r\n\r\n
Data (2 bytes)
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: (text/plain)
Content-Disposition: form-data; name="file"; filename="ex.txt"\r\n
Content-Type: text/plain\r\n\r\n
Line-based text data: text/plain
lore ipsum blabbla
Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:
Content-Disposition: form-data; name="seq"\r\n\r\n
Data (2 bytes)
服务器是否有可能依赖零件的顺序?根据分段上传表格:订单有保证吗?,显然是?如果是这样,是否可以使用 requests 库显式强制订单?在这种情况下更糟的是:文件和文本值混合在一起。
因此,强制执行命令似乎相当困难。这是我目前的做法:
s.post('http://www.url.com', files=files,data = form_values)
EDIT2: 我在请求插件中进行了修改,以确保部件的顺序与原始请求中的相同。这并不能解决问题,所以我想我的问题没有直接的解决方案。我会向网站的开发人员发送邮件,希望他们能帮助我!