Ситуации:Как передать массив с помощью веб-запроса
Мы собираем автоматически много сообщений от некоторых веб-служб (PowerShell скрипта, запускающих каждую ночь), и каждый день в ручном режиме (перетаскивание на веб-формы), эти отчеты загружаются в нашу БД.
Теперь наш ИТ-отдел предоставил нам API, который может обрабатывать эту работу без взаимодействия с пользователем.
Проблема:
Как было написано в сопроводительном письме (об этом API) он ждет reports[n]
массив с файлом. Это может быть сделано с PHP и завитка:
$report = 'report_20160825.{8302F59C-E1E4-410F-BE37-A24CCD7E515E}.zip';
$cfile = new CURLFile(realpath($report),'application/zip',$report);
$PostData = array("reports[0]"=>$cfile);
Но как отправить массив с именем reports[n]
с помощью PowerShell?
То, что я пробовал:
$url = "https://test.example.com/uploadAPI/upload.php"
$Source = "D:\report_20160825.{8302F59C-E1E4-410F-BE37-A24CCD7E515E}.zip"
$contentType = "multipart/form-data"
$Username = "ApiUploadKey"
$Headers = @{Authorization="Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:" -f $Username)))}
$FileContens = get-content $Source
$PostData = @{"reports[0]" = $FileContens;}
#$reports = @($FileContens,'application/zip',$Source)
(Invoke-WebRequest -uri $url -Method POST -Headers $Headers -Body $PostData -ContentType $contentType).Content
#Invoke-RestMethod -uri $url -Method POST -Headers $Headers -Body $PostData -ContentType $contentType
Это дает мне ответ, который я передаю не-а-отчет.
EDIT 2016-10-11
Дальнейшие исследования довести меня до этого answer и этого article. Я пытался использовать boundary
:
clear
$url = "https://test.example.com/uploadAPI/upload.php"
$filename = "report_20160825.{8302F59C-E1E4-410F-BE37-A24CCD7E515E}.zip"
$Source = "D:\"+$filename
$Username = "ApiUploadKey"
$Headers = @{Authorization="Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:" -f $Username)))}
$FileContens = get-content $Source
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$fileBin = [IO.File]::ReadAllBytes($Source)
$fileEnc = $enc.GetString($fileBin)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`n"
$contentType = "multipart/form-data; boundary=--$boundary"
#$bodyLines = "--"+$boundary+$LF+"Content-Disposition: form-data; name=`"reports[]`"; filename=`""+$filename+"`""+$LF+$LF+"Content-Type: application/zip"+$LF+"--"+$boundary+"--"+$LF+$LF+$FileContens+$LF+"--"+$boundary
$bodyLines = (
"--$boundary", #I have tried reports[0] here too
"Content-Disposition: form-data; name=`"reports[]`"; filename=`"$filename`"", # filename= is optional
"Content-Type: application/zip",
"",
#$FileContens,
$fileEnc,
"--$boundary--"
) -join $LF
try {
#Invoke-WebRequest -Uri "https://asrp.cntd.ru/uploadAPI/" -Headers $Headers -WebSession $ws
Invoke-RestMethod -Uri $url -Body $bodyLines -Method POST -Headers $Headers -ContentType $contentType -TimeoutSec 50
}
catch [System.Net.WebException] {
Write-Error("FAILED to reach '$url': $_")
throw $_
}
Но с теми же результатами.
Также я попытался это:
$wc = new-object System.Net.WebClient
$wc.Credentials = new-object System.Net.NetworkCredential("ApiUploadKey","")
ls "D:\*.zip" | foreach {
$wc.UploadFile('https://test.example.com/uploadAPI/upload.php', $_.FullName)
write-host $_.FullName
}
И еще одно решение от этого answer:
Invoke-RestMethod -Uri $url -InFile $Source -ContentType "multipart/form-data" -Method POST -Headers $Headers
Всегда же ответ - не отчет
EDIT 2016-10- 17
локон
Я скачал curl
для окон. И использовать его как:
curl.exe https://test.example.com/uploadAPI/upload.php --user ApiUploadKey: --form "reports[0][email protected]:\report_746_226255_20161010_1635.zip;type=application/zip"
И это дало мне:
[{"code" : 102 , "guid" : "{23CE9F7F-BEC8-4D4C-8AC3-2865CFA94FBD}" , "id" : "5804902bc73a2475177464", "filename" : "report_746_226255_20161010_1635.zip"}]
Так с завитком он отлично работает!
стельку
Не знаю точно, что войти чтобы оставлять сообщения.
Когда я отправить файл, как это:
POST https://test.example.com/uploadAPI/upload.php
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: test.example.com
Authorization: Basic ...
Content-Length: 21075175
тело запроса:
---------------------------acebdf13572468
Content-Disposition: form-data; name="reports[]"; filename="report_746_226254_20161010_1320.{B67A9D89-368B-4665-96AC-77C2CA0F4766}.zip"
Content-Type: application/zip
<@INCLUDE *D:\report_746_226254_20161010_1320.{B67A9D89-368B-4665-96AC-77C2CA0F4766}.zip*@>
---------------------------acebdf13572468--
я получил
HTTP/1.1 200 OK
Date: Mon, 17 Oct 2016 10:04:43 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2h PHP/7.0.6
X-Powered-By: PHP/7.0.6
Set-Cookie: SESSION_UPLOAD_ID=.....; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Connection: close
Content-Length: 193
Content-Encoding: none
Accept-Ranges: bytes
Content-Type: text/html; charset=UTF-8
[{"code" : 102 , "guid" : "{B67A9D89-368B-4665-96AC-77C2CA0F4766}" , "id" : "5804a23be4152532018928", "filename" : "report_746_226254_20161010_1320.{B67A9D89-368B-4665-96AC-77C2CA0F4766}.zip"}]
try set content-type, -ContentType "multipart/form-data" –
Я попробовал. Как видите, существует переменная '$ contentType'. Он использовался как '-ContentType $ contentType' в' Invoke-WebRequest'. Должен отредактировать мой вопрос. – gofr1
TL; DR. Возможно, вы можете упростить вопрос. –