Beego 中应使用 c.Input.Language() 获取 Accept-Language 解析后的语言标签,而非手动解析 Header;需启用 i18n 模块、正确配置语言包路径与格式,并确保 LangTypes 包含请求语言。

Beego 中如何读取 Accept-Language 请求头
Beego 的 c.Ctx.Request 是标准 *http.Request,所以可以直接调用 Header.Get("Accept-Language") 获取原始值。但注意:这个字段可能为空、格式不规范(如多个语言项用逗号分隔、带权重 q=0.8),不能直接当语言标识符用。
推荐做法是用 Beego 自带的 c.Input.Language() —— 它已封装了解析逻辑,会按权重排序并返回最匹配的可用语言标签(如 "zh-CN"、"en-US"),前提是你的语言包目录结构和配置已就位。
-
c.Input.Language()内部调用beego.BConfig.WebConfig.Language配置的默认语言兜底 - 若未启用国际化(i18n),该方法始终返回空字符串
- 不要手动解析
Accept-Language后再做字符串截断(比如取前两位),这会破坏区域变体区分(zh-CN和zh-TW语义不同)
启用 i18n 模块并组织语言包目录
Beego 的国际化支持依赖 beego/i18n 子模块,不是开箱即用的。必须显式初始化,且语言包文件需严格按命名和路径存放。
- 在
main.go初始化阶段调用i18n.SetMessagePath("conf/lang"),指定根目录(如conf/lang/zh-CN.ini、conf/lang/en-US.ini) - 每个
.ini文件内容为标准 key-value 格式:home.title = 首页,key 不含引号,等号前后可有空格 - 文件名必须是语言标签全小写、中划线分隔(
zh-cn.ini有效,zh_CN.ini或ZH-CN.ini会被忽略) - Beego 不自动扫描子目录,
conf/lang/zh-CN/这种嵌套结构无效
在 Controller 中动态加载对应语言包
语言包加载发生在请求进入时,但 Beego 默认只根据配置的 LangTypes 和请求头做一次匹配,不会为每个 Controller 单独重载。真正“动态”的关键在于:确保 c.Input.Language() 返回值准确,并在模板或响应中用它查值。
- 在
Prepare()方法里调用c.Data["Lang"] = c.Input.Language(),把当前语言传给模板,避免重复计算 - 模板中用
{{i18n . "home.title"}}查找翻译,函数会自动使用当前请求上下文的语言环境 - 如果需要在 Controller 里手动获取翻译,用
i18n.Tr("zh-CN", "home.title"),但硬编码语言标签就失去动态意义,应改用i18n.Tr(c.Input.Language(), "home.title") - 注意:若
c.Input.Language()返回空,i18n.Tr会 fallback 到beego.BConfig.WebConfig.DefaultLanguage(需在conf/app.conf显式设为defaultlanguage = "en-US")
常见错误:Accept-Language 匹配失败却无提示
最常踩的坑是语言包没生效,但控制台不报错,页面显示原始 key(如 home.title)。这不是代码异常,而是 i18n 模块静默 fallback 的结果。
- 检查
conf/app.conf是否设置了enableexec = true(Beego 2.x+ 要求开启执行模式才能加载 i18n) - 确认
LangTypes配置包含你支持的语言,例如:langtypes = zh-CN,en-US,ja-JP;漏掉zh-CN就算请求头是zh-CN也会 fallback - 用
c.Ctx.Request.Header.Get("Accept-Language")打印原始值,验证前端是否真发了该 header(某些测试工具或 curl 默认不带) - i18n 初始化必须在
beego.Run()之前完成,放在init()函数里最稳妥
语言标签匹配是大小写敏感且格式严格的,哪怕多一个空格或错一位连字符,都会导致 fallback 到默认语言——这点容易被忽略,调试时建议先打印 c.Input.Language() 看实际返回值。


















