gorilla/mux 怎么实现 /{locale}/hi 和 /hi 指向同一个路由

33 天前
 dzdh

实现 URL 级的多语言路由

想实现全局有个默认语言比如中间件判断 accept-language 。设置 ctx 。

然后访问 /hi 就显示默认语言(mux.Vars()[locale]等于"",而不是 hi) 访问 /en/hi 就强制显示成 en 语言。

gorilla 可以实现自定义 matcher 吗?或者有其他路由组件能支持吗?

897 次点击
所在节点    Go 编程语言
7 条回复
bv
33 天前
以标准库为例:

```
package main

import (
"fmt"
"net/http"
)

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/hi", Language)
mux.HandleFunc("/{lang}/hi", Language)

http.ListenAndServe(":9999", mux)
}

func Language(w http.ResponseWriter, r *http.Request) {
lang := r.PathValue("lang")
if lang == "" {
lang = r.Header.Get("Accept-Language")
}

fmt.Println(lang)
w.Write([]byte(lang))
}
```
hingle
33 天前
有个方案,可以中间件获取到 locale 后,重定向到 /{locale}/hi
dzdh
33 天前
@bv 这样还是定义了两个路由。。

@hingle 那要是有十几个一两百个路由呢。比如 /{locale}/product/{title} 访问 /product/a-b-c-d-e 也要要求能匹配到路由
xiaoyiyu
33 天前
```go
var global = http.NewServeMux()
var mux1 = http.NewServeMux()
mux1.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {

})
global.Handle("/", mux1)
global.Handle("/{locale}/", mux1)
http.ListenAndServe("", global)
```
这样试下
dzdh
33 天前
@xiaoyiyu 这个思路真的是。。。。我试试
dzdh
33 天前
@xiaoyiyu 貌似也不行。
xiaoyiyu
32 天前
```go
var langs = map[string]bool{
"cn": true,
"en": true,
"jp": true,
"ru": true,
}

func main() {
var global = http.NewServeMux()
var mux = http.NewServeMux()

mux.HandleFunc("/api/asd", func(w http.ResponseWriter, r *http.Request) {
fmt.Println("hello asadsdd")
fmt.Fprintf(w, "hello format")
})

global.Handle("/{locale}/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println(r.PathValue("locale"))
if lng := r.PathValue("locale"); langs[lng] {
http.StripPrefix("/"+lng, mux).ServeHTTP(w, r)
} else {
mux.ServeHTTP(w, r)
}
}))

http.ListenAndServe(":12345", global)
}
```

➜ curl http://localhost:12345/en/api/asd
hello format%
➜ curl http://localhost:12345/cn/api/asd
hello format%
➜ curl http://localhost:12345/api/asd
hello format%
➜ curl http://localhost:12345/ad/api/asd
404 page not found

看效果是满足了的
@dzdh
@dzdh

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1033143

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX