【问题标题】:POST request with Multipart/form-data. Content-type not correct带有 Multipart/form-data 的 POST 请求。内容类型不正确
【发布时间】:2013-08-08 20:20:06
【问题描述】:

我们正在尝试使用 python(使用 python-requests a.t.m.)编写一个脚本来向内容必须是 MultipartFormData 的站点发出 POST 请求。 当我们使用wireshark手动执行这个POST请求(通过填写网站上的表格并发布)时,出现了(短版):

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

奇怪的是,数据包的“通用类型”确实是多部分/表单数据,但发送的单个项目(键 = 'name',值 = '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)

服务器是否可以根据零件的顺序进行计数?根据Multipart upload form: Is order guaranteed?,显然是?如果是这样,是否可以使用 requests 库显式强制订单? 在这种情况下更糟的是:文件和文本值混合在一起。

所以强制执行命令似乎相当困难。这是我目前的做法:

s.post('http://www.url.com', files=files,data = form_values)

EDIT2: 我在请求插件中进行了修改,以确保部件的顺序与原始请求中的相同。这并不能解决问题,所以我想我的问题没有直接的解决方案。我会向网站的开发人员发送邮件,希望他们能帮助我!

【问题讨论】:

    标签: python urllib python-requests


    【解决方案1】:

    您的代码看起来正确。

    requests.post('http://url.com', files={'name': 'John Doe'})
    

    ...并且应该发送一个“multipart/form-data”帖子。

    确实,我收到了这样的帖子:

    Accept-Encoding: gzip, deflate, compress
    Connection: close
    Accept: */*
    Content-Length: 188
    Content-Type: multipart/form-data; boundary=032a1ab685934650abbe059cb45d6ff3
    User-Agent: python-requests/1.2.3 CPython/2.7.4 Linux/3.8.0-27-generic
    
    --032a1ab685934650abbe059cb45d6ff3
    Content-Disposition: form-data; name="name"; filename="name"
    Content-Type: application/octet-stream
    
    John Doe
    --032a1ab685934650abbe059cb45d6ff3--
    

    知道为什么你会得到那个奇怪的 Content-Type 标头:

    Content-Type: application/x-pandoplugin
    

    我将首先从您的机器中完全删除 Pando Web 插件,然后再次尝试您的 python-requests 代码。 (或在不同的机器上尝试)

    【讨论】:

    • 我们在不同的机器上进行了尝试。在另一个是应用程序/x-uplaypc。似乎随机插件“接管”了默认的内容类型。我也不知道为什么会这样。
    • 非常值得怀疑,但是你们用netrc吗?
    • 不,至少我不知道。我想我几乎解决了这个问题,所以请看一下更新后的问题。既然你是请求的合作者,也许你知道答案?提前致谢!
    • @CoreyGoldberg 对于不同的名称和文件名值,您有什么建议?例如:name = "name"; filename="something else" content-Type: video/mp4 请帮忙。
    【解决方案2】:

    Python 使用系统范围的配置文件来“猜测”文件的 mime 类型。如果这些插件使用它们的自定义 mime 类型注册您的文件扩展名,那么您最终会将其放入。

    最安全的方法是进行适合您发送的特定服务器的自己的 mime 类型猜测,并且只对您没有想到的扩展使用本机 python mime 类型猜测。

    我不知道您如何使用 python-requests 手动指定内容类型,但我希望它应该是可能的。

    【讨论】:

      【解决方案3】:

      从今天开始,您可以:

      response = s.post('http://url.com', files={'name': (filename, contents, content_type)})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-05
        • 2014-10-31
        • 2019-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-09
        相关资源
        最近更新 更多