简体   繁体   English

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

[英]How to use GET method of Invoke-WebRequest to build a query string

Is there a standard way to make use of Invoke-WebRequest or Invoke-RestMethod in PowerShell to get information from a web page using a query string? 有没有一种标准方法可以使用PowerShell中的Invoke-WebRequest或Invoke-RestMethod来使用查询字符串从网页获取信息?

For example, I know that the following when used with a well formed JSON end point will work: 例如,我知道当与格式良好的JSON端点一起使用时,以下内容将起作用:

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

along with the equivalent Invoke-WebMethod. 以及等效的Invoke-WebMethod。 An important aspect of this is the content type and ConvertTo-JSON which manages the transformation of the parameters specified in the -Body part in to a standard form, including the array aspect of the "Children" field. 其中一个重要方面是内容类型和ConvertTo-JSON,它管理-Body部分中指定的参数到标准形式的转换,包括“Children”字段的数组方面。

What is an equivalent way to do this with a website which uses, say, a comma delimited convention for managing array arguments in the URL or an approach such as "Children[]=Abe&Children[]=Karen&Children=Jo"? 有一个等效的方法是使用一个网站,例如,使用逗号分隔的约定来管理URL中的数组参数或方法,如“Children [] = Abe&Children [] = Karen&Children = Jo”?

Is there a content type that I'm missing and is there an equivalent ConvertTo-?? 是否有我缺少的内容类型,并且有一个等价的ConvertTo- ?? that I can use? 我可以用吗? My guess is that someone has had to do this before. 我的猜测是有人不得不这样做。

For context this is an often used way of encoding an array parameter in the URL and is commonly seen in PHP web sites. 对于上下文,这是一种在URL中编码数组参数的常用方法,常见于PHP网站。

passing arrays as url parameter 将数组作为url参数传递

Edit Removed references to PHP except for specific context and adjusted the title to refer to a query string. 编辑删除对PHP的引用,但特定上下文除外,并调整标题以引用查询字符串。 The problem is about encoding a query string not PHP per se. 问题是关于编码查询字符串而不是PHP本身。

It seems that the server running PHP is irrelevant here. 似乎运行PHP的服务器在这里无关紧要。 I think you're asking how to send key/value pairs as query string parameters. 我想你问的是如何将键/值对作为查询字符串参数发送。

If that's the case, you're in luck. 如果是这样的话,你很幸运。 Both Invoke-RestMethod and Invoke-WebRequest will take a [hashtable] in the body and construct your query string for you: 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

Edit 编辑

Now seeing that the issue is that you want a query string parameter to have multiple values, essentially an array, this rules out the data types you can pass to the body parameter. 现在看到问题是您希望查询字符串参数具有多个值,实际上是一个数组,这将排除您可以传递给body参数的数据类型。

So instead, let's build the URI piece by piece first by starting with a [UriBuilder] object and adding on a query string built using an [HttpValueCollection] object (which allows duplicate keys). 因此,让我们首先通过以[UriBuilder]对象开始并添加使用[HttpValueCollection]对象(允许重复键)构建的查询字符串来[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

The following appears to work reasonably well as a "first cut". 以下似乎作为“第一次切割”工作得相当好。 Thanks to @briantist for the key point which was to use the .NET HttpValueCollection. 感谢@briantist关于使用.NET HttpValueCollection的关键点。 It seems we have to "roll our own" way of building the query string. 看来我们必须“推出自己的”构建查询字符串的方式。

The below code snip shows a simple way to transform the hash table containing parameters and values in to a well formed query string by simply traversing the hash table. 下面的代码片段显示了一种简单的方法,通过简单地遍历哈希表,将包含参数和值的哈希表转换为格式良好的查询字符串。 One limitation is that nesting is not permitted (a parameter value cannot be a complex type such as a hash table). 一个限制是不允许嵌套(参数值不能是复杂类型,例如哈希表)。

# 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM