Trong gói http của Go, làm cách nào để lấy chuỗi truy vấn theo yêu cầu ĐĂNG?


114

Tôi đang sử dụng httpgói từ Go để giải quyết yêu cầu POST. Làm cách nào để truy cập và phân tích cú pháp nội dung của chuỗi truy vấn từ Requestđối tượng? Tôi không thể tìm thấy câu trả lời từ tài liệu chính thức.


Một điều cần lưu ý, nếu bạn đang sử dụng cURL để gửi yêu cầu và bạn sử dụng r.FormValue("id")để tìm nạp một tham số truy vấn, bạn không thể gửi tôi qua dữ liệu biểu mẫu trong cURL (tức là curl 0.0.0.0:8888 -d id=foobarsẽ không hoạt động). Bạn phải gửi nó qua truy vấn params ( curl 0.0.0.0:8888?id=foobar).

Câu trả lời:


145

Theo định nghĩa , chuỗi truy vấn nằm trong URL. Bạn có thể truy cập URL của yêu cầu bằng req.URL( doc ). Đối tượng URL có một Query()phương thức ( doc ) trả về một Valueskiểu, đơn giản là một map[string][]stringtrong các tham số QueryString.

Nếu những gì bạn đang tìm kiếm là dữ liệu ĐĂNG như được gửi bởi biểu mẫu HTML , thì đây (thường) là một cặp khóa-giá trị trong nội dung yêu cầu. Bạn đã trả lời đúng trong câu trả lời của mình rằng bạn có thể gọi ParseForm()và sau đó sử dụng req.Formtrường để nhận bản đồ của các cặp khóa-giá trị, nhưng bạn cũng có thể gọi FormValue(key)để nhận giá trị của một khóa cụ thể. Điều này gọi ParseForm()nếu được yêu cầu và nhận các giá trị bất kể chúng được gửi như thế nào (tức là trong chuỗi truy vấn hoặc trong phần thân yêu cầu).


2
Cảm ơn vì sự lựa chọn.
Fabien

2
Tôi thấy phương thức 'req.FormValue (key)' nhanh hơn và cung cấp cho bạn tất cả mã cần thiết để phân tích cú pháp trước url.
OnlyAngel

6
req.URL.RawQuerytrả về mọi thứ sau ?yêu cầu GET, nếu điều đó hữu ích.
kouton

Tôi thấy điều đó thật thú vị khi req.Form là mảng trống trừ khi req.formValue ("some_field") được gọi cùng lúc.
Qian Chen

Cảm ơn rất nhiều! @kouton
Aditya Varma

127

Đây là một ví dụ cụ thể hơn về cách truy cập các tham số GET. Đối Requesttượng có một phương thức phân tích cú pháp chúng ra cho bạn được gọi là Truy vấn :

Giả sử một URL yêu cầu như http: // host: port / something? Param1 = b

func newHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("GET params were:", r.URL.Query())

  // if only one expected
  param1 := r.URL.Query().Get("param1")
  if param1 != "" {
    // ... process it, will be the first (only) if multiple were given
    // note: if they pass in like ?param1=&param2= param1 will also be "" :|
  }

  // if multiples possible, or to process empty values like param1 in
  // ?param1=&param2=something
  param1s := r.URL.Query()["param1"]
  if len(param1s) > 0 {
    // ... process them ... or you could just iterate over them without a check
    // this way you can also tell if they passed in the parameter as the empty string
    // it will be an element of the array that is the empty string
  }    
}

Cũng lưu ý "các khóa trong bản đồ Giá trị [tức là Giá trị trả về của Truy vấn ()] phân biệt chữ hoa chữ thường."


4
Một câu trả lời trước đó đã được đề cập và được liên kết với các tài liệu thực hiện điều đó (và nó không có ví dụ sẽ gây hoảng sợ với tham chiếu lát ngoài giới hạn nếu trường mong muốn không có, hãy sử dụng r.URL.Query().Get("moviename")để tránh sai lầm nghiêm trọng này).
Dave C

1
Cảm ơn bạn về thông tin. Vâng, tài liệu hơi khó hiểu đối với tôi, vì vậy tôi đăng bài này như một "ví dụ thực hành" trong trường hợp hữu ích. Đã sửa lỗi kiểm tra nil. Sử dụng Getphương thức này chỉ trả về giá trị đầu tiên nếu có nhiều, vì vậy đây là một ví dụ về nhiều. Thông tin hữu ích, cảm ơn bạn!
rogerdpack

Ngoài ra tôi không nghĩ rằng bạn có thể so sánh một chuỗi để nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang tức là chuỗi = "" là hợp lệ!
James Milner

Tôi không nghĩ rằng mã sẽ biên dịch, ví dụ đã hoàn thành. Bạn không thể so sánh chuỗi trống Values.Get()trả về với nil. golang.org/pkg/net/url/#Values
Daniel Farrell

19

Dưới đây là một ví dụ:

value := r.FormValue("field")

để biết thêm thông tin. về gói http, bạn có thể truy cập tài liệu của nó tại đây . FormValuevề cơ bản trả về giá trị POST hoặc PUT hoặc giá trị GET, theo thứ tự đó, giá trị đầu tiên nó tìm thấy.


8

Đây là một ví dụ đơn giản, hoạt động:

package main

import (
    "io"
    "net/http"
)
func queryParamDisplayHandler(res http.ResponseWriter, req *http.Request) {
    io.WriteString(res, "name: "+req.FormValue("name"))
    io.WriteString(res, "\nphone: "+req.FormValue("phone"))
}

func main() {
    http.HandleFunc("/example", func(res http.ResponseWriter, req *http.Request) {
        queryParamDisplayHandler(res, req)
    })
    println("Enter this in your browser:  http://localhost:8080/example?name=jenny&phone=867-5309")
    http.ListenAndServe(":8080", nil)
}

nhập mô tả hình ảnh ở đây



5

Các từ dưới đây đến từ tài liệu chính thức.

Biểu mẫu chứa dữ liệu biểu mẫu được phân tích cú pháp, bao gồm cả tham số truy vấn của trường URLdữ liệu biểu mẫu POST hoặc PUT . Trường này chỉ khả dụng sau khi ParseForm được gọi.

Vì vậy, các mã mẫu như bên dưới sẽ hoạt động.

func parseRequest(req *http.Request) error {
    var err error

    if err = req.ParseForm(); err != nil {
        log.Error("Error parsing form: %s", err)
        return err
    }

    _ = req.Form.Get("xxx")

    return nil
}
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.