powershell invoke-restmethod multipart / form-data

时间:2016-03-28 18:47:38

标签: rest powershell curl

我目前正在尝试使用REST API将文件上传到Web服务器。如上所述,我正在使用PowerShell。卷曲这没问题。电话看起来像这样:

curl -H "Auth_token:"$AUTH_TOKEN -H "Content-Type:multipart/form-data" -X POST -F appInfo='{"name": "test","description": "test"}' -F uploadFile=@/test/test.test https://server/api/

但是当我使用Invoke-Restmethod命令将它导出到powershell时,我完全无能为力。据我搜索,不可能使用Invoke-Rest方法。 https://www.snip2code.com/Snippet/396726/PowerShell-V3-Multipart-formdata-example 但即使有了Snipped,我也不够聪明,因为我不想上传两个文件,而是上传一个文件和一些参数。

如果有人能让我回到赛道上,我将非常感激:o 谢谢!

7 个答案:

答案 0 :(得分:10)

应该非常直截了当。取自this answer

$Uri = 'https://server/api/';
$Headers = @{'Auth_token'=$AUTH_TOKEN};
$FileContent = [IO.File]::ReadAllText('C:\test\test.test');
$Fields = @{'appInfo'='{"name": "test","description": "test"}';'uploadFile'=$FileContent};

Invoke-RestMethod -Uri $Uri -ContentType 'multipart/form-data' -Method Post -Headers $Headers -Body $Fields;

如果文件不是文本文件,您可能需要使用[IO.File]::ReadAllBytes()

如果你上传一个巨大的文件,这也可能效果不佳。

答案 1 :(得分:10)

@Bacon-Bits的答案对我来说似乎不起作用。我的服务器拒绝了它有一个可能格式错误的表单数据正文: - (

我找到了{{3}},为了我的目的将它修剪了一下。这是我的最终结果:

JSON.parse(response.body, object_class: OpenStruct)

答案 2 :(得分:4)

我需要同时传递标头和更多参数(insert=truedebug=true)以及文件内容。这是我的版本,通过@jklemmack扩展了脚本。

param([string]$path)

$Headers = @{Authorization = "Bearer ***************"}
$Uri = 'https://host:8443/api/upload'

$fileBytes = [System.IO.File]::ReadAllBytes($path);
$fileEnc = [System.Text.Encoding]::GetEncoding('ISO-8859-1').GetString($fileBytes);
$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "`r`n";

$bodyLines = ( 
    "--$boundary",
    "Content-Disposition: form-data; name=`"insert`"$LF",
    "true$LF",
    "--$boundary",
    "Content-Disposition: form-data; name=`"debug`"$LF",
    "true$LF",    
    "--$boundary",
    "Content-Disposition: form-data; name=`"file`"; filename=`"$path`"",
    "Content-Type: application/octet-stream$LF",
    $fileEnc,
    "--$boundary--$LF" 
) -join $LF

Invoke-RestMethod -Uri $Uri -Headers $Headers -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines

答案 3 :(得分:3)

使用PowerShell Core,可以使用新的self.add_widget(game) 参数立即使用。

请参阅:https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7

-Form

答案 4 :(得分:1)

因此,我最近对此进行了相当多的研究,发现确实可以匹配curl功能,但是如何正确地处理multipart / form-data尚不是很明显。上面所有的回答都涵盖了难题的重要部分,但是我将在这里尝试将所有问题联系在一起,以供下一个对不起的家伙尝试在本机Powershell中实现curl功能。

@jklemmack's解决方案是使我走上正轨的解决方案,并且是最灵活的解决方案,因为它允许您专门构造表单数据内容,同时控制边界和数据获取方式在其中格式化。

对于任何尝试执行此操作的人,我认为重要的是,您必须使用Fiddler(.net)或Burp Suite(java)等适当的Web调试代理来武装自己,以便可以详细检查每个REST调用以了解传递给API的数据的特定格式。

在我的特定情况下,我注意到curl在表单数据的每个部分上方插入了一条空行-因此,扩展@jklemmack的示例,它将类似于以下内容:

    $bodyLines = (
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield1`"",
        '',
        $formdata1,
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield2`"",
        '',
        $formdata2,
        "--$boundary",
        "Content-Disposition: form-data; name=`"formfield3`"; filename=`"$name_of_file_being_uploaded`"",
        "Content-Type: application/json",
        '',
        $content_of_file_being_uploaded,
        "--$boundary--"
    ) -join $LF

希望这可以为将来节省很多时间!

我也仍然同意,如果您需要从头开始,并且可以选择直接使用curl本机二进制文件(同时确保对安全性和合规性的尽职调查),则可以利用它的成熟性和便利性它提供的。使用卷曲。最好由curl社区广泛地测试和维护这种多部分逻辑,而不是内部开发人员或运营团队的责任。

答案 5 :(得分:0)

我尝试使用Invoke-RestMethod执行以下curl命令时遇到了一些麻烦:

curl --request POST \
  --url https://example.com/upload_endpoint/ \
  --header 'content-type: multipart/form-data' \
  --form 'file=@example.csv'
  -v

就我而言,事实证明直接在powershell中使用curl要容易得多。

$FilePath = "C:\example.csv"
$CurlExecutable = "C:\curl-7.54.1-win64-mingw\bin\curl.exe"

Write-Host "CurlFile" $CurlFile
$CurlArguments = '--request', 'POST', 
                'https://example.com/upload_endpoint/',
                '--header', "'content-type: multipart/form-data'",
                '--form', "file=@$FilePath"
                '-v',

& $CurlExecutable @CurlArguments

只需在curl's website上获取您的操作系统的可执行文件。

我为什么要使用curl?

Curl是免费的开源软件,它易于调试并支持许多操作系统。它可以直接在命令行上使用,并支持许多协议。许多工具都可以生成curl命令。

答案 6 :(得分:0)

尝试在 Windows 8.1 上使用 powershell v4 将文件上传到我的 upload.php 的痛苦

# This code works and matches to a Firefox 78.6.0esr upload transmission verified via wireshark

$FilePath = 'c:\Temp\file-to-upload.txt';
$URL = 'http://127.0.0.1/upload.php';

$fileBytes = [System.IO.File]::ReadAllBytes($FilePath);
$fileEnc = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "\r\n";

$bodyLines = "--$boundary $LF Content-Disposition: form-data; name='file'; filename='file-to-upload.txt' $LF Content-Type: application/octet-stream $LF $fileEnc $LF --$boundary-- $LF";

Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=$boundary" -Body $bodyLines

供参考,upload.php为:

<?php
    $uploaddir = '/var/www/uploads/';
    $uploadfile = $uploaddir . $_FILES['file']['name'];
    move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)
?>

Wireshark 示例

POST /upload.php HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 6.3; en-US) WindowsPowerShell/4.0
Content-Type: multipart/form-data; boundary=96985b62-451a-41fa-9eca-617e3599797c
Host: 127.0.0.1
Content-Length: 284
Connection: Keep-Alive

--96985b62-451a-41fa-9eca-617e3599797c \r\n Content-Disposition: form-data; name='file'; filename='ftp.txt' \r\n Content-Type: application/octet-stream \r\n open 127.0.0.1 21
anonymous
anonymous
bin
put file-to-upload.txt
quit
 \r\n --96985b62-451a-41fa-9eca-617e3599797c-- \r\nHTTP/1.1 200 OK
Date: Sat, 02 Jan 2021 22:11:03 GMT
Server: Apache/2.4.46 (Debian)
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

相关问题