【问题标题】:Robotframework.request - How to make a POST request with content "multipart/form-data"Robotframework.request - 如何使用内容“multipart/form-data”发出 POST 请求
【发布时间】:2019-04-27 00:37:58
【问题描述】:

我想使用 RequestsLibrary 在 Robot Framework 中使用“Content-Type: multipart/form-data”发出 POST 请求,但似乎没有任何效果。 发出此请求的关键字如下所示:

*** Variables ***
&{API_CREDS}  username=myusername  password=mypwd

*** Keywords ***
Get token
    # Assumes that session has been created
    [Arguments]  ${Session_id}
    &{headers}=  create dictionary  Content-Type=multipart/form-data
    ${response}=  Post Request  ${Session_id}  ${AUTH_TOKEN_URL_PATH}  data=${API_CREDS}   headers=${headers}
    should be equal as integers  ${response.status_code}  200
    [Return]  ${response.json()['token']}

但实际发送的 POST 请求不包含“Content-Type”标头,正文只是一个原始的data={'username' = 'myusername', ' password' = 'mypwd'}

我已经尝试了很多我发现的东西,但没有任何效果。 Robot Framework 的RequestsLibrary 是否真的支持发送带有“Content-Type: multipart/form-data”的 POST 请求?如果是,这是怎么做的?

PS:我在Windows 10Python 3.7.1 上使用Robot Framework。 POST 请求实际上是发送的,但它不包含 Content-Type 标头,也不包含 form-data 有效负载,如上所述。

【问题讨论】:

    标签: python python-requests robotframework


    【解决方案1】:

    使用的底层 python 库 - requests 具有一些处理多部分“表单数据”内容的特性。它主要使用它作为请求的一部分发送文件(上传功能);粗略地说,当它解析您的参数时,它会剥离标题,因为没有要发送的文件。此外,如果它没有这样做,它的设计目的不是为了扣除多部分有效负载中的不同部分 - 例如它不会自动将每个键值对放在单独的部分中。

    为了克服这一点,通常使用files 参数,将不同部分的内容作为参数传递。这样做时,requests 库将自动设置表单数据标题,并将内容分成几部分。
    下面是如何在 RF 中做到这一点,解释如下:

    ${data}=    Evaluate    {'username': (None, 'myusername'), 'password': (None, 'mypwd')}
    ${response}=  Post Request  ${Session_id}  ${AUTH_TOKEN_URL_PATH}  files=${data}
    

    使用Post Request 关键字中的files 参数,您的有效负载将按原样传递给requests post 方法。您不需要显式设置标题,库会为您完成。

    作为参数传递的是字典,值是部分的内容。如您所见,实际值是 python 元组,因为您想覆盖部件中的文件名。用一个例子可以更好地解释这一点;如果数据是这样的,值就是一个简单的刺:

    ${data}=    Evaluate    {'username': 'myusername', 'password': 'mypwd'}
    

    ,那么payload就会变成:

    --7579227dh785568ha91866339229add786
    Content-Disposition: form-data; name="username"; filename="username"
    
    myusername
    --7579227dh785568ha91866339229add786
    Content-Disposition: form-data; name="password"; filename="password"
    
    mypwd
    --7579227dh785568ha91866339229add786--
    

    注意每个部分都有一个“文件名”属性,等于参数名称。

    当值是一个元组时,它的第一个成员设置部分的“文件名”属性;当它是None 时,根本就没有“文件名”,产生这样的结果:

    --7579227dh785568ha91866339229add786
    Content-Disposition: form-data; name="username"
    
    myusername
    --7579227dh785568ha91866339229add786
    Content-Disposition: form-data; name="password"
    
    mypwd
    --7579227dh785568ha91866339229add786--
    

    ,这可能是你的目标。

    【讨论】:

    • 非常感谢托多。 RequestsLibrary 需要在文档方面做一些工作,所以当我得到你全面的有效答案时,我正在检查实际的 python 实现。
    • @Todor Minakov 字段名称为'inputData'且值为'input'的情况下如何处理:["Hello World"] 如下图 ${form_data} Evaluate {' eventId':(无,'423'),'actionDefID':(无,'648'),'serviceInstanceId':(无,'3'),'inputData':{“input”:[“Hello_PRASHANT”]}我收到错误请求错误,我很确定问题出在最后一个字段,但不知道如何解决。
    猜你喜欢
    • 2019-06-19
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多