9

我正在使用mux包,它似乎工作得很好,只是它似乎不支持复杂的路由,或者至少我不明白它是如何工作的。我有以下几条路线:

router := mux.NewRouter()
router.HandleFunc("/{productid}/{code}", product)
router.HandleFunc("/{user}", userHome)
router.HandleFunc("/search/price", searchPage)

所以我有两个问题:

  • 如何定义通配符路由,例如 /search/price/* 以便 /search/price/29923/rage/200/color=red 等请求可以匹配?

  • 是否可以将自定义条件添加到现有路线?例如,如果路由是/{productid}/{code}并且函数 x 返回true,则使用 this handlerTrue,如果返回则false使用handlerFalse

我试图 .MatcherFunc(myfunction(ip)bool)在路由中添加类似的东西,但它抱怨路由器没有这样的方法。

目前我正在处理处理程序中的“自定义”条件。

4

4 回答 4

12

您可以使用正则表达式。就像是

router.HandleFunc(`/search/price/{rest:[a-zA-Z0-9=\-\/]+}`, searchPage)

这样,rest只会捕获所有内容,因此在您的示例rest中将是29923/rage/200/color=red. 您需要在代码中解析它。

不过,您可能需要一些类似的可选参数。

router.HandleFunc(`/search{price:(\/price\/[0-9]+)?}{rage:(\/rage\/[0-9]+)?}{color:(\/color=[a-z]+)?}`, searchPage)

之后,您会得到仍然需要解析的vars和price = "/price/29923",但它更容易,并且您可以控制哪些参数是有效的。如果您跳过某些参数,它会按预期工作,例如。只会给出一个空变量,但仍然匹配。rage = "/rage/200"color = "/color=red"/search/price/29923/color=redrage

我不太明白你的第二个问题。

于 2014-02-10T23:57:27.140 回答
0

我不太确定您是否需要一条“通配符”路线:您只需要一条带有多个参数的路线:

/search/price/{price}/rage/{id}/color将起作用,请注意查询字符串不需要包含在匹配器中(您可以通过 访问这些字符串request.URL.Query,而您可以通过 访问多路复用器变量mux.Vars。您还可以使用正则表达式来缩小接受的参数范围。

它还有助于区分您的用户和产品路线,可能通过在它们前面加上/user/{id}/products/{id}/{code}(特别是语义)。

就目前MatcherFunc而言,您需要确保您的函数使用与 MatcherFunc 相同的签名(这是一种类型):func MatchIPAddresses(*http.Request, *RouteMatch) bool会解决它。您可以通过Request结构访问 IP 地址,方法是检查r.RemoteAddr或者r.Header.Get("X-Forwarded-For")您是否希望在代理后面。我通常检查两者是否为空("")。

即(粗略;您可以稍微清理一下!)

func MatchIPAddresses(r *http.Request, rm *RouteMatch) bool {
    if r.RemoteAddr == 8.8.8.8 {
        return true
    } else if r.Header.Get("X-Forwarded-For") == 8.8.8.8 {
        return true
    }

    return false
}
于 2014-02-09T22:36:12.507 回答
0

要将自定义 MatcherFunc 与 gorilla mux 一起使用,您需要确保您的匹配器实际上是 mux.MatcherFunc 类型。这是因为 MatcheFunc 不是接口类型

// From mux/route.go line 303
// MatcherFunc is the function signature used by custom matchers.
type MatcherFunc func(*http.Request, *RouteMatch) bool

因此,您必须执行以下操作:

var myMatcher mux.MatcherFunc = func(request *http.Request, match *mux.RouteMatch) bool {
  // Your custom logic
  return trueOrFalse
}

// You can then use it on your route like this.
router := mux.NewRouter()
router.HandleFunc("/{productid}/{code}", product).MatcherFunc(myMatcher)
于 2019-05-22T06:57:11.097 回答
-1

使用 chi 作为路由器,您可以执行以下操作:

由于正则表达式从不匹配斜杠/,因此您可以简单地匹配*

例如对于/search/price/29923/rage/200/color=red

router.Get(`/search/price/*`, priceHandler)

func DashboardFilesHandler(w http.ResponseWriter, r *http.Request) {
    path := myhandler.UrlParam(r, "*")
    // path will be '29923/rage/200/color=red'
}

另见:https ://godoc.org/github.com/go-chi/chi

名称后跟冒号的占位符允许正则表达式匹配,例如 {number:\d+}。正则表达式语法是 Go 的普通正则表达式 RE2 语法,只是不支持包含 { 或 } 的正则表达式,并且永远不会 匹配 /。允许匿名正则表达式模式,在占位符的冒号前使用空字符串,例如 {:\d+}

星号的特殊占位符与请求的URL的其余部分匹配。 模式中的任何尾随字符都将被忽略。这是唯一将匹配 / 字符的占位符。

于 2018-05-09T08:28:12.190 回答