powershell调用restmethod多部分/表单数据
我目前正在尝试使用RESTAPI将文件上载到Web服务器。如前所述,我正在为此使用PowerShell。对于curl,这是没有问题的。该呼叫如下所示:powershell调用restmethod多部分/表单数据,rest,powershell,curl,Rest,Powershell,Curl,我目前正在尝试使用RESTAPI将文件上载到Web服务器。如前所述,我正在为此使用PowerShell。对于curl,这是没有问题的。该呼叫如下所示: 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://serv
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方法。
但即使是被剪掉了,我也没有足够的智慧让它工作,因为我不想上传两个文件,而是一个文件和一些参数
如果有人能让我重回正轨,我将非常感激:哦
谢谢 应该很直截了当。取自: 如果文件不是文本文件,则可能需要使用
[IO.File]::ReadAllBytes()
如果您正在上载一个大文件,这也可能无法正常工作。我在尝试使用以下
curl
命令时遇到了一些问题:
curl——请求发布\
--网址https://example.com/upload_endpoint/ \
--标题“内容类型:多部分/表单数据”\
--格式“file=@example.csv”
-五
在我的例子中,直接在powershell中使用curl
要容易得多
$FilePath=“C:\example.csv”
$CurlExecutable=“C:\curl-7.54.1-win64-mingw\bin\curl.exe”
$CurlArguments='--request',POST',
'https://example.com/upload_endpoint/',
“--标题”,“内容类型:多部分/表单数据”,
“--form',“file=@$FilePath”
“-v”,
#调试上述变量以查看将要执行的操作
写入主机“FilePath”$FilePath
写入主机“可执行文件”$FilePath
写入主机“CurlArguments”$CurlArguments
#执行带有参数的curl命令
&$CurlExecutable@CurlArguments
只需抓取操作系统上的可执行文件
为什么我应该使用curl
而不是powershell的调用restmethod
?
- 与Powershell一样,Curl也是免费的开源软件
- 易于调试并支持多种操作系统
- 也可用于其他壳中
- 支持多种协议
- 许多工具都可以生成curl命令
- 支持上传大于2GB的文件(感谢Shukri Adams的帮助)
- @这个答案似乎对我不起作用。我的服务器拒绝了它,其表单数据体可能存在错误:-(
我找到了,为了我的目的把它修剪了一点。以下是我的最终结果:
$FilePath = 'c:\temp\temp.txt';
$URL = 'http://your.url.here';
$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",
"Content-Disposition: form-data; name=`"file`"; filename=`"temp.txt`"",
"Content-Type: application/octet-stream$LF",
$fileEnc,
"--$boundary--$LF"
) -join $LF
Invoke-RestMethod -Uri $URL -Method Post -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines
所以,我最近一直在努力解决这个问题,发现匹配curl功能确实是可能的,但如何正确处理多部分/表单数据还不是很明显。上面所有的回答都涵盖了这个难题的重要部分,但我将尝试在这里把它们联系在一起,以供下一个尝试使用curl功能的家伙参考o在本机Powershell中实现curl功能 解决方案使我走上了正确的道路,而且是最灵活的,因为它允许您专门构造表单数据内容,控制两个边界,以及数据在其中的格式化方式 对于任何试图这样做的人,我认为使用合适的web调试代理(如Fiddler(.net)或Burp Suite(java))来武装自己是很重要的,这样您就可以详细检查每个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。最好由整个curl社区积极测试和维护此多部分逻辑,而不是由您的内部开发或操作团队承担责任。对于PowerShell Core,这应该与新的
-Form
一起开箱即用>参数
见:
我需要传递头和一些其他参数(
insert=true
和debug=true
)以及文件内容
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
尝试在windows 8.1上使用powershell v4将文件上载到my 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)
?>
你能在我的中告诉我一些事情吗?请在投票时留下评论。我仍然认为
curl
是一个非常好的解决方案,因为它可以被测试,即使你没有访问Windows机器,因为curl
是多平台的。如果上面的解决方案对你不起作用,请在这里留下评论。上面的解决方案已经测试过了在Windows 7和Windows 10上运行。它也应该在较旧的系统上运行。是的,但我没有curl
。我在远程系统上运行(事实上超过300个),但没有安装。我想将其嵌入调用脚本
脚本块中以上载日志文件。在我的方案中,Pure PowerShell是赢家。我知道,Pure PowerShell解决方案确实是最好的。我个人在写我的答案时,在这里没有其他答案。在您管理300个服务的情况下呃,我建议使用资源调配工具(ansible、salt等)管理它们。在所有这些计算机上发送powershell脚本与在所有这些计算机上获取curl可执行文件的工作是一样的。当然,我不知道您的确切使用情况。如果您已经在服务器上进行了远程执行,如果找不到可执行文件,没有任何东西会阻止您从同一脚本下载curl。希望您找到解决方案,很好幸运的是,我们的场景是锁定远程信息亭,空中传输能力有限
# 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
<?php
$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . $_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)
?>
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