Robotframework.request-如何发出内容为“ multipart / form-data”的POST请求

jua*_*era 3 python robotframework python-requests

我想使用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']}
Run Code Online (Sandbox Code Playgroud)

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

我尝试了很多发现可以搜索的东西,但是没有任何效果。RequestsLibraryRobot Framework实际上是否支持发送带有“ Content-Type:multipart / form-data”的POST请求?

PS:我使用机器人框架Windows 10Python 3.7.1。POST请求实际上是发送的,但不包含Content-Type标头,也不包含表单数据有效载荷,如上所述。

Tod*_*kov 5

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

为了克服这个问题,通常使用files参数,将不同部分的内容作为参数传递。这样,requests库将自动设置表单数据标题,并将内容分成几部分。
在RF中执行此操作的方法如下:

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

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

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

${data}=    Evaluate    {'username': 'myusername', 'password': 'mypwd'}
Run Code Online (Sandbox Code Playgroud)

,则有效负载将变为:

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

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

mypwd
--7579227dh785568ha91866339229add786--
Run Code Online (Sandbox Code Playgroud)

注意每个部分如何具有“文件名”属性,该属性等于参数名。

当值是元组时,它的第一个成员设置零件的“文件名”属性;当它是时None,根本没有“文件名”,从而产生以下结果:

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

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

mypwd
--7579227dh785568ha91866339229add786--
Run Code Online (Sandbox Code Playgroud)

,这可能是您的目标。