增加多语言支持
This commit is contained in:
102
middleware/language.go
Normal file
102
middleware/language.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LanguageKey context中存储语言的key
|
||||
type languageKey struct{}
|
||||
|
||||
// LanguageHeaderName 语言请求头名称
|
||||
const LanguageHeaderName = "X-Language"
|
||||
|
||||
// AcceptLanguageHeaderName Accept-Language 请求头名称
|
||||
const AcceptLanguageHeaderName = "Accept-Language"
|
||||
|
||||
// DefaultLanguage 默认语言
|
||||
const DefaultLanguage = "zh-CN"
|
||||
|
||||
// GetLanguageFromContext 从context中获取语言
|
||||
func GetLanguageFromContext(ctx context.Context) string {
|
||||
if lang, ok := ctx.Value(languageKey{}).(string); ok && lang != "" {
|
||||
return lang
|
||||
}
|
||||
return DefaultLanguage
|
||||
}
|
||||
|
||||
// Language 语言处理中间件
|
||||
// 从请求头 X-Language 或 Accept-Language 读取语言信息,如果未传递则使用默认语言 zh-CN
|
||||
// 语言信息会存储到context中,可以通过 GetLanguageFromContext 获取
|
||||
func Language(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// 1. 优先从 X-Language 请求头获取(显式指定)
|
||||
lang := r.Header.Get(LanguageHeaderName)
|
||||
|
||||
// 2. 如果未设置,从 Accept-Language 请求头解析
|
||||
if lang == "" {
|
||||
acceptLang := r.Header.Get(AcceptLanguageHeaderName)
|
||||
if acceptLang != "" {
|
||||
lang = parseAcceptLanguage(acceptLang)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果都未设置,使用默认语言
|
||||
if lang == "" {
|
||||
lang = DefaultLanguage
|
||||
}
|
||||
|
||||
// 将语言存储到context中
|
||||
ctx := context.WithValue(r.Context(), languageKey{}, lang)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// LanguageWithDefault 语言处理中间件(可自定义默认语言)
|
||||
// defaultLanguage: 默认语言,如果未指定则使用 zh-CN
|
||||
func LanguageWithDefault(defaultLanguage string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// 1. 优先从 X-Language 请求头获取(显式指定)
|
||||
lang := r.Header.Get(LanguageHeaderName)
|
||||
|
||||
// 2. 如果未设置,从 Accept-Language 请求头解析
|
||||
if lang == "" {
|
||||
acceptLang := r.Header.Get(AcceptLanguageHeaderName)
|
||||
if acceptLang != "" {
|
||||
lang = parseAcceptLanguage(acceptLang)
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果都未设置,使用指定的默认语言
|
||||
if lang == "" {
|
||||
lang = defaultLanguage
|
||||
}
|
||||
|
||||
// 将语言存储到context中
|
||||
ctx := context.WithValue(r.Context(), languageKey{}, lang)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// parseAcceptLanguage 解析 Accept-Language 请求头
|
||||
// 返回第一个语言代码(去掉权重信息)
|
||||
func parseAcceptLanguage(acceptLang string) string {
|
||||
if acceptLang == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 分割语言列表
|
||||
parts := strings.Split(acceptLang, ",")
|
||||
if len(parts) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 取第一个语言代码,去掉权重信息(如 ";q=0.9")
|
||||
firstLang := strings.Split(parts[0], ";")[0]
|
||||
firstLang = strings.TrimSpace(firstLang)
|
||||
|
||||
return firstLang
|
||||
}
|
||||
Reference in New Issue
Block a user