Подтвердить что ты не робот

Как отправить multipart/form-data с помощью PowerShell Invoke-RestMethod

Я пытаюсь отправить файл через Invoke-RestMethod в том же контексте, что и curl с ключом -F.

Пример скручивания

curl -F [email protected]"/path-to-file.name" "https://uri-to-post"

В powershell я пробовал что-то вроде этого:

$uri = "https://uri-to-post"
$contentType = "multipart/form-data"
$body = @{
    "FileName" = Get-Content($filePath) -Raw
}

Invoke-WebRequest -Uri $uri -Method Post -ContentType $contentType -Body $body
}

Если я проверяю скрипач, я вижу, что тело содержит необработанные двоичные данные, но я получаю ответ 200 назад, пока не было отправлено никакой полезной нагрузки.

Я также попытался использовать параметр -InFile без везения.

Я видел несколько примеров, использующих класс .net, но пытался сохранить это с помощью новых команд Powershell 3.

Есть ли у кого-нибудь какие-либо рекомендации или опыт в этой работе?

4b9b3361

Ответ 1

Проблема заключалась в том, что API требовал дополнительных параметров. Первоначальный запрос требовал некоторых параметров для приема необработанного содержимого и указания имени файла/размера. После установки этого параметра и возврата правильной ссылки для отправки я смог использовать:

Invoke-RestMethod -Uri $uri -Method Post -InFile $filePath -ContentType "multipart/form-data"

Ответ 2

Принятый ответ не будет выполнять запрос multipart/form-data, а скорее запрос application/x-www-form-urlencoded, заставляющий заголовок Content-Type присваивать значение, которое тело не содержит.

Один способ отправить отформатированный запрос multipart/form-data с помощью PowerShell:

$ErrorActionPreference = 'Stop'

$fieldName = 'file'
$filePath = 'C:\Temp\test.pdf'
$url = 'http://posttestserver.com/post.php'

Try {
    Add-Type -AssemblyName 'System.Net.Http'

    $client = New-Object System.Net.Http.HttpClient
    $content = New-Object System.Net.Http.MultipartFormDataContent
    $fileStream = [System.IO.File]::OpenRead($filePath)
    $fileName = [System.IO.Path]::GetFileName($filePath)
    $fileContent = New-Object System.Net.Http.StreamContent($fileStream)
    $content.Add($fileContent, $fieldName, $fileName)

    $result = $client.PostAsync($url, $content).Result
    $result.EnsureSuccessStatusCode()
}
Catch {
    Write-Error $_
    exit 1
}
Finally {
    if ($client -ne $null) { $client.Dispose() }
    if ($content -ne $null) { $content.Dispose() }
    if ($fileStream -ne $null) { $fileStream.Dispose() }
    if ($fileContent -ne $null) { $fileContent.Dispose() }
}

Ответ 3

Я нашел этот post и немного изменил его

$fileName = "..."
$uri = "..."

$currentPath = Convert-Path .
$filePath="$currentPath\$fileName"

$fileBin = [System.IO.File]::ReadAlltext($filePath)
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyLines = (
    "--$boundary",
    "Content-Disposition: form-data; name=`"file`"; filename=`"$fileName`"",
    "Content-Type: application/octet-stream$LF",
    $fileBin,
    "--$boundary--$LF"
) -join $LF

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