Thực hiện yêu cầu GET và xây dựng Chuỗi truy vấn


85

Tôi còn khá mới với cờ vây và chưa hiểu rõ mọi thứ. Trong nhiều ngôn ngữ hiện đại Node.js, Angular, jQuery, PHP, bạn có thể thực hiện yêu cầu GET với các tham số chuỗi truy vấn bổ sung.

Thực hiện điều này trong cờ vây không hề đơn giản và tôi thực sự chưa thể tìm ra. Tôi thực sự không muốn phải nối một chuỗi cho mỗi yêu cầu mà tôi muốn thực hiện.

Đây là kịch bản mẫu:

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))
}

Trong ví dụ này, bạn có thể thấy có một URL yêu cầu biến GET của api_key với khóa api của bạn làm giá trị. Vấn đề là điều này trở nên khó được mã hóa dưới dạng:

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

Có cách nào để xây dựng chuỗi truy vấn này một cách động không ?? Hiện tại, tôi sẽ cần phải tập hợp URL trước bước này để nhận được phản hồi hợp lệ.


1
Vì vậy, điều gì là sai khi nối một chuỗi?
Salvador Dali

4
Tôi cho rằng không có gì, nhưng nó không thực sự là một sự say mê tao nhã, chỉ nghĩ rằng có một cách tốt hơn để làm mọi thứ trong cờ vây. Bạn thấy các thay đổi hành động, phương thức và sau đó bạn phải xâu chuỗi mọi thứ lại với nhau.
Rudi Strydom

2
Bạn có thể sử dụng url.Values's Encodephương pháp. Bạn cũng có thể sử dụng URL.Stringđể tạo toàn bộ URL.
Dave C

Câu trả lời:


208

Như một người bình luận đã đề cập, bạn có thể lấy Valuestừ net/urlđó có một Encodephương pháp. Bạn có thể làm điều gì đó như thế này ( req.URL.Query()trả về hiện có 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


1
Cảm ơn bạn tuyệt vời! Đó chính xác là những gì tôi đang tìm kiếm!
Rudi Strydom

Tuyệt vời để thử nghiệm quá!
Kyle Chadha

Bất kỳ giải pháp nào để tạo các tham số chuỗi truy vấn theo thứ tự mong muốn của bạn? Các khóa được sắp xếp theo Encode()phương pháp.
artificerpi

1
@artificerpi nếu nó là quan trọng vì một lý do nào đó, bạn có thể thực hiện lại những gì họ làm bên trong phương thức Mã hóa golang.org/src/net/url/url.go?s=24222:24253#L845 Nhưng tôi sẽ tự hỏi tại sao nó lại quan trọng.
jcbwlkr

3
Bạn không cần sử dụng NewRequest nếu bạn không làm gì với nó. Bạn chỉ có thể sử dụng url.Parse("https://something.com/")thay thế hoặc thậm chí tạo một đối tượng URL trực tiếp.
Richard

34

Sử dụng r.URL.Query()khi bạn thêm vào truy vấn hiện có, nếu bạn đang xây dựng một nhóm tham số mới, hãy sử dụng url.Valuescấu trúc như vậy

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
}

11

Sử dụng NewRequestchỉ để tạo một URL là một việc làm quá mức cần thiết. Sử dụng net/urlgói:

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())
}

Sân chơi: https://play.golang.org/p/YCTvdluws-r


câu trả lời đơn giản nhất và hoạt động hoàn hảo, cảm ơn
Jake Boomgaarden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.