如何在 Go 中更改 URL 查询参数

725 阅读2分钟

在 Go 中更改 URL 查询参数

在这篇简短的文章中,我们将讨论如何在 Go 中添加、修改或删除 URL 查询字符串参数。为了说明,我们将看看如何更改此 URL:

https://example.com?name=alice&age=28&gender=female

对此:

https://example.com?name=alice&age=29&occupation=carpenter

如果您想就地更改 URL 查询字符串

// Use url.Parse() to parse a string into a *url.URL type. If your URL is
// already a url.URL type you can skip this step.
urlA, err := url.Parse("https://example.com?name=alice&age=28&gender=female")
if err != nil {
    log.Fatal(err)
}

// Use the Query() method to get the query string params as a url.Values map.
values := urlA.Query()

// Make the changes that you want using the Add(), Set() and Del() methods. If
// you want to retrieve or check for a specific parameter you can use the Get()
// and Has() methods respectively. 
values.Add("occupation", "carpenter")
values.Del("gender")
values.Set("age", strconv.Itoa(29))

// Use the Encode() method to transform the url.Values map into a URL-encoded
// string (like "age=29&name=alice...") and assign it back to the URL. Note 
// that the encoded values will be sorted alphabetically based on the parameter 
// name. 
urlA.RawQuery = values.Encode()

fmt.Printf("urlA: %s", urlA.String())

会打印出:

urlA: https://example.com?age=29&name=alice&occupation=carpenter

如果要创建 URL 的克隆但具有不同的查询字符串,同时保持原始 URL 不变,则需要url.URL先创建原始结构的副本。

有几种方法可以做到这一点。您可以重新解析 URL,

uri0, _ := url.Parse("<https://hey.com/?was=true>")  
uri1, _ := url.Parse(uri0.String())

也可以取消引用原始文件url.URL并制作副本,如下所示:

// This is equivalent to: var newUrl url.URL = *originalUrl newUrl := *originalUrl

当你这样做时,你创建了一个新的newURL类型变量url.URL,它被初始化为 的(取消引用的)值*originalURL。这意味着它newURL在内存中的地址与originalURL.

综上所述,创建具有不同参数的新 URL 的模式是:

urlA, err := url.Parse("https://example.com?name=alice&age=28&gender=female")
if err != nil {
    log.Fatal(err)
}

// Make a copy of the original url.URL.
urlB := *urlA

// Make the param changes to the new url.URL type...
values := urlB.Query()

values.Add("occupation", "carpenter")
values.Del("gender")
values.Set("age", strconv.Itoa(29))

urlB.RawQuery = values.Encode()

fmt.Printf("urlA: %s\n", urlA.String()) // This will be unchanged.
fmt.Printf("urlB: %s\n", urlB.String()) // This will have the new params.

运行它会打印出:

urlA: https://example.com?name=alice&age=28&gender=female
urlB: https://example.com?age=29&name=alice&occupation=carpenter

您可以在任何时候想要“克隆”URL 并对其进行更改时使用此技术。例如,要创建具有不同路径的 URL 的克隆,可以这样做:

urlA, err := url.Parse("https://example.com/foo")
if err != nil {
    log.Fatal(err)
}

urlB := *urlA

urlB.Path = "/bar"

fmt.Printf("%s\n", urlA.String()) // Prints https://example.com/foo
fmt.Printf("%s\n", urlB.String()) // Prints https://example.com/bar