Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
powershell调用restmethod多部分/表单数据_Rest_Powershell_Curl - Fatal编程技术网

powershell调用restmethod多部分/表单数据

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

我目前正在尝试使用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://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