我目前正在尝试使用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 谢谢!
答案 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=true
和debug=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)
参数立即使用。
-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命令。
答案 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