如何使用Invoke-WebRequest的GET方法来构建查询字符串

时间:2015-09-07 16:21:41

标签: arrays json powershell

是否有一种标准方法可以使用PowerShell中的Invoke-WebRequest或Invoke-RestMethod来使用查询字符串从网页获取信息?

例如,我知道当与格式良好的JSON端点一起使用时,以下内容将起作用:

$Parameters = @{
  Name = 'John'
  Children = 'Abe','Karen','Jo'
}
$Result = Invoke-WebRequest -Uri 'http://.....whatever' -Body ( $Parameters | ConvertTo-Json)  -ContentType application/json -Method Get

以及等效的Invoke-WebMethod。这方面的一个重要方面是内容类型和ConvertTo-JSON,它管理-Body部分中指定的参数到标准形式的转换,包括" Children"的数组方面。字段。

使用一个网站来执行此操作的等效方法,该网站使用逗号分隔的约定来管理URL中的数组参数或方法,例如" Children [] = Abe& Children [] = Karen& ;儿童=乔"

是否有我缺少的内容类型,并且是否存在等效的ConvertTo- ??我可以用吗?我的猜测是有人不得不这样做。

对于上下文,这是经常使用的  在URL中编码数组参数的方法,常见于PHP网站。

passing arrays as url parameter

修改 除了特定的上下文之外,删除了对PHP的引用,并调整了标题以引用查询字符串。问题是关于编码查询字符串而不是PHP本身。

2 个答案:

答案 0 :(得分:6)

似乎运行PHP的服务器在这里无关紧要。我想您正在询问如何将键/值对作为查询字符串参数发送。

如果是这样的话,那你很幸运。 Invoke-RestMethodInvoke-WebRequest都会在正文中使用[hashtable]并为您构建查询字符串:

$Parameters = @{
  Name = 'John'
  Children = 'Abe','Karen','Jo'
}
Invoke-WebRequest -Uri 'http://www.example.com/somepage.php' -Body $Parameters -Method Get # <-- optional, Get is the default

修改

现在看到问题是你希望查询字符串参数有多个值,本质上是一个数组,这就排除了你可以传递给body参数的数据类型。

因此,让我们首先通过从[UriBuilder]对象开始并添加使用[HttpValueCollection]对象(允许重复键)构建的查询字符串来逐个构建URI。

$Parameters = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
$Parameters['Name'] = 'John'
foreach($Child in @('Abe','Karen','Joe')) {
    $Parameters.Add('Children', $Child)
}

$Request = [System.UriBuilder]'http://www.example.com/somepage.php'

$Request.Query = $Parameters.ToString()

Invoke-WebRequest -Uri $Request.Uri -Method Get # <-- optional, Get is the default

答案 1 :(得分:0)

以下似乎可以很好地作为第一次切割&#34;。感谢@briantist关于使用.NET HttpValueCollection的关键点。我们似乎必须自己推动自己的&#34;构建查询字符串的方法。

下面的代码片段显示了一种简单的方法,通过简单地遍历哈希表,将包含参数和值的哈希表转换为格式良好的查询字符串。一个限制是不允许嵌套(参数值不能是复杂类型,如哈希表)。

# Setup, parameters is now a PowerShell hash table
# we convert that on the fly to an appropriate URL
$Parameters = @{
    Name = 'John'
    Children = 'Abe','Karen','Jo'
}
$Uri = 'http://example.com/somepage.php'
$AddSquareBracketsToArrayParameters = $true



$HttpValueCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
foreach ($Item in $Parameters.GetEnumerator()) {
    if ($Item.Value.Count -gt 1) {
        # It is an array, so treat that as a special case.
        foreach ($Value in $Item.Value) {
            # Add each item in the array, optionally mark the name of the parameter
            # to indicate it is an array parameter.
            $ParameterName = $Item.Key
            if ($AddSquareBracketsToArrayParameters) { $ParameterName += '[]' }                 
            $HttpValueCollection.Add($ParameterName, $Value)
        }
    } else {
        # Add the scalar value.
        $HttpValueCollection.Add($Item.Key,$Item.Value)
    }
}
# Build the request and load it with the query string.
$Request  = [System.UriBuilder]($Uri)
$Request.Query = $HttpValueCollection.ToString()

# Now fire off the request.
Invoke-WebRequest -Uri $Request.Uri