是否有一种标准方法可以使用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本身。
答案 0 :(得分:6)
似乎运行PHP的服务器在这里无关紧要。我想您正在询问如何将键/值对作为查询字符串参数发送。
如果是这样的话,那你很幸运。 Invoke-RestMethod
和Invoke-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