'language.MatchStrings()'返回垃圾

Max*_*AST 2 internationalization go

我正在执行以下代码:

var languageMatcher = language.NewMatcher([]language.Tag{
    language.English, // Default if no match
    language.French,
})

lang, _ := r.Cookie("lang")
accept := r.Header.Get("Accept-Language")

var cookieValue = ""

if cookie != nil {
    cookieValue = lang.String()
}

tag, _ := language.MatchStrings(languageMatcher, cookieValue, accept)

log.Debugf(ctx, fmt.Sprintf("Localized %s to %s. cookie: %s | header: %s", path, tag.String(), cookieValue, accept))

http.Redirect(w, r, "/"+tag.String()+path, 302)
Run Code Online (Sandbox Code Playgroud)

大部分来自 GoDoc

它在大多数情况下都能正常工作,但有时(从从未访问过该网站的计算机上以私有模式进行浏览时,或者从浏览器中删除整个缓存(无lang cookie)时);该language.MatchStrings函数在tag变量(如)中返回一堆垃圾en-u-rg-uszzzz

这是我的log.Debugf输出:

Localized / to en-u-rg-uszzzz. cookie: | header: en-US,en;q=0.9

知道什么是错的吗?

fra*_*567 5

根据文档,语言匹配器可以在标签上添加Unicode扩展名:

Match方法返回的索引与t中匹配标签的索引相对应,但是通过相应首选标签的Unicode扩展('u')进行了扩展。这允许透明地传递用户区域设置选项。

这解释了奇怪的en-u-rg-uszzzz价值。当匹配器为我们提供数组中匹配语言的索引时,一种解决方法是使用它来检索原始语言:

var availableLanguages = []language.Tag{
    language.English, // Default if no match
    language.French,
}
var languageMatcher = language.NewMatcher(availableLanguages)

lang, _ := r.Cookie("lang")
accept := r.Header.Get("Accept-Language")

var cookieValue = ""

if lang != nil { // Be careful: the variable name was wrong
    cookieValue = lang.String()
}

_, i := language.MatchStrings(languageMatcher, cookieValue, accept)

log.Debugf(ctx, fmt.Sprintf("Localized %s to %s. cookie: %s | header: %s", path, availableLanguages[i].String(), cookieValue, accept))

http.Redirect(w, r, "/"+availableLanguages[i].String()+path, 302)
Run Code Online (Sandbox Code Playgroud)

有点hacky,但是可以用。

问候!