7

我在 HTTPS(端口 10443)上运行并使用子路由:

mainRoute := mux.NewRouter()
mainRoute.StrictSlash(true)
mainRoute.Handle("/", http.RedirectHandler("/static/", 302))
mainRoute.PathPrefix("/static/").Handler(http.StripPrefix("/static", *fh))

// Bind API Routes
apiRoute := mainRoute.PathPrefix("/api").Subrouter()

apiProductRoute := apiRoute.PathPrefix("/products").Subrouter()
apiProductRoute.Handle("/", handler(listProducts)).Methods("GET")

和功能:

func listProducts(w http.ResponseWriter, r *http.Request) (interface{}, *handleHTTPError) {
    vars := mux.Vars(r)

    productType, ok := vars["id"]
    log.Println(productType)
    log.Println(ok)
}

okfalse,我不知道为什么。我在?type=modelURL 之后做了一个简单的操作。

4

2 回答 2

33

当您输入一个 URL 时,就像somedomain.com/products?type=model您指定一个查询字符串,而不是一个变量一样。

Go 中的查询字符串通过以下方式访问r.URL.Query- 例如

vals := r.URL.Query() // Returns a url.Values, which is a map[string][]string
productTypes, ok := vals["type"] // Note type, not ID. ID wasn't specified anywhere.
var pt string
if ok {
    if len(productTypes) >= 1 {
        pt = productTypes[0] // The first `?type=model`
    }
}

正如你所看到的,这可能有点笨拙,因为它必须考虑到映射值是空的,以及一个 URL 的可能性,比如somedomain.com/products?type=model&this=that&here=there&type=cat一个键可以被多次指定。

根据gorilla/mux 文档,您可以使用路由变量:

   // List all products, or the latest
   apiProductRoute.Handle("/", handler(listProducts)).Methods("GET")
   // List a specific product
   apiProductRoute.Handle("/{id}/", handler(showProduct)).Methods("GET")

这是您将使用的地方mux.Vars

vars := mux.Vars(request)
id := vars["id"]

希望这有助于澄清。除非您特别需要使用查询字符串,否则我建议您使用变量方法。

于 2015-07-12T21:10:30.103 回答
2

解决此问题的更简单方法是在您的路由中添加查询参数Queries,例如:

apiProductRoute.Handle("/", handler(listProducts)).
                Queries("type","{type}").Methods("GET")

您可以使用以下方法获取它:

v := mux.Vars(r)
type := v["type"]

注意:最初发布问题时这可能是不可能的,但是当我遇到类似问题并且大猩猩文档提供帮助时,我偶然发现了这一点。

于 2017-09-27T13:29:21.420 回答