执行 GET 请求并构建 Querystring

我是新来的,还不是很了解所有的东西。在许多现代语言 Node.js、 Angular、 jQuery 和 PHP 中,您可以使用附加的查询字符串参数来执行 GET 请求。

在围棋中做这件事并不像看起来那么简单,而且我现在还没有真正弄明白。我真的不想为我想要做的每个请求连接一个字符串。

下面是示例脚本:

package main


import (
"fmt"
"io/ioutil"
"net/http"
)


func main() {
client := &http.Client{}


req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular", nil)
req.Header.Add("Accept", "application/json")
resp, err := client.Do(req)


if err != nil {
fmt.Println("Errored when sending request to the server")
return
}


defer resp.Body.Close()
resp_body, _ := ioutil.ReadAll(resp.Body)


fmt.Println(resp.Status)
fmt.Println(string(resp_body))
}

在这个示例中,您可以看到有一个 URL,它需要一个 api _ key 的 GET 变量,其中 api 键作为值。问题在于,这种方法变得很难以下面的形式进行编码:

req, _ := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular?api_key=mySuperAwesomeApiKey", nil)

有没有办法动态构建这个查询字符串? ?目前,我需要在此步骤之前组装 URL,以获得有效的响应。

215840 次浏览

正如一位评论者提到的,你可以从 net/url获得 Values,它有一个 Encode方法。您可以这样做(req.URL.Query()返回现有的 url.Values)

package main


import (
"fmt"
"log"
"net/http"
"os"
)


func main() {
req, err := http.NewRequest("GET", "http://api.themoviedb.org/3/tv/popular", nil)
if err != nil {
log.Print(err)
os.Exit(1)
}


q := req.URL.Query()
q.Add("api_key", "key_from_environment_or_flag")
q.Add("another_thing", "foo & bar")
req.URL.RawQuery = q.Encode()


fmt.Println(req.URL.String())
// Output:
// http://api.themoviedb.org/3/tv/popular?another_thing=foo+%26+bar&api_key=key_from_environment_or_flag
}

Http://play.golang.org/p/l5xcrw9vig

在添加现有查询时使用 r.URL.Query(),如果要构建新的参数集,则使用 url.Values结构,如下所示

package main


import (
"fmt"
"log"
"net/http"
"net/url"
"os"
)


func main() {
req, err := http.NewRequest("GET","http://api.themoviedb.org/3/tv/popular", nil)
if err != nil {
log.Print(err)
os.Exit(1)
}


// if you appending to existing query this works fine
q := req.URL.Query()
q.Add("api_key", "key_from_environment_or_flag")
q.Add("another_thing", "foo & bar")


// or you can create new url.Values struct and encode that like so
q := url.Values{}
q.Add("api_key", "key_from_environment_or_flag")
q.Add("another_thing", "foo & bar")


req.URL.RawQuery = q.Encode()


fmt.Println(req.URL.String())
// Output:
// http://api.themoviedb.org/3/tv/popularanother_thing=foo+%26+bar&api_key=key_from_environment_or_flag
}

仅仅为了创建一个 URL 而使用 NewRequest是过分的。使用 net/url包:

package main


import (
"fmt"
"net/url"
)


func main() {
base, err := url.Parse("http://www.example.com")
if err != nil {
return
}


// Path params
base.Path += "this will get automatically encoded"


// Query params
params := url.Values{}
params.Add("q", "this will get encoded as well")
base.RawQuery = params.Encode()


fmt.Printf("Encoded URL is %q\n", base.String())
}

操场: https://play.golang.org/p/YCTvdluws-r