【问题标题】:python set-up boundary for POST using multipart/form-data with requestspython 使用多部分/表单数据和请求为 POST 设置边界
【发布时间】:2023-03-04 03:14:02
【问题描述】:

我想使用请求发送文件,但服务器使用设置为***** 的固定边界工作。我只能发送一个文件,但 requests 模块会创建一个随机边界。如何覆盖它?

import requests

url='http://xxx.xxx.com/uploadfile.php'
fichier= {'uploadedfile':open('1103290736_2016_03_23_13_32_55.zip','rb')}
headers2={'Connection':'Keep-Alive','User-Agent':'Dalvik/1.6.0 (Linux; U; Android 4.4.2; S503+ Build/KOT49H)','Accept-Encoding':'gzip'}
session= requests.Session()
session.post(url,headers=headers2,files=fichier)
session.close()

【问题讨论】:

  • 那是一台非常损坏的服务器。你不能改为修复服务器吗?
  • 您必须进行自己的编码,并设置包含边界的Content-Type 标头。
  • 我知道如何设置 Content-Type 但不知道如何进行自己的编码。能给个例子或链接吗

标签: python http post python-requests


【解决方案1】:

男孩,那是一个非常损坏的服务器。如果可以,请修复服务器。

你不能告诉requests选择什么边界。您可以改为使用email.mime package 构建自己的multipart/form-data 有效负载:

from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

related = MIMEMultipart('form-data', '*****')  # second argument is the boundary.
file_part = MIMEApplication(
    open('1103290736_2016_03_23_13_32_55.zip', 'rb').read(),
    # optional: set a subtype: 'zip',
)
file_part.add_header('Content-disposition', 'form-data; name="uploadedfile"')
related.attach(file_part)

body = related.as_string().split('\n\n', 1)[1]
headers = dict(related.items())
headers['User-Agent'] = 'Dalvik/1.6.0 (Linux; U; Android 4.4.2; S503+ Build/KOT49H)'

r = session.post(url, data=body, headers=headers)

这会将Content-Type: multipart/form-data; boundary="*****" 设置为标题,而正文使用***** 作为边界(带有适当的-- 前后缀)。

【讨论】:

    【解决方案2】:

    一个简单的替代方法是使用requests-toolbelt;以下示例取自 GitHub issue thread:

    from requests_toolbelt import MultipartEncoder
    
    fields = {
    # your multipart form fields
    }
    
    m = MultipartEncoder(fields, boundary='my_super_custom_header')
    r = requests.post(url, headers={'Content-Type': m.content_type}, data=m.to_string())
    

    但是,这会引入额外的依赖,可以是slow to upload large files

    【讨论】:

    • 能否请你给我字段的例子,我试过了,我得到 ValueError: Data must not be a string。 ,我已经通过stackoverflow.com/questions/27553082/…
    • 你测试过这个吗?它似乎没有按预期工作。我刚刚尝试过,正文中的边界与标题中的边界不同。类似于链接的 github 问题的顶部。
    【解决方案3】:

    您实际上可以直接使用 requests 模块来执行此操作:

    files = {'file': ('filename', open('filename', 'rb'), 'text/plain')}
    body, content_type = requests.models.RequestEncodingMixin._encode_files(files, {})
    
    # this way you ensure having the same boundary defined in
    # the multipart/form-data contetn-type header
    # the form-data
    
    data = body
    headers = {
        "Content-Type": content_type
    }
    response = requests.post(
        endpoint,
        data=data,
        headers=headers
    )
    

    这对我有用。否则我会收到这样的错误:

    "errorMessage":"所需的请求部分'文件'不存在"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 2012-11-27
      • 2016-05-01
      • 2017-10-05
      • 2018-09-16
      • 2011-01-19
      相关资源
      最近更新 更多