最简单可靠的方式是直接读取 document.documentelement.lang,它始终存在、实时反映语言值,未声明时返回空字符串;其他方法如 queryselector 或正则提取需注意执行时机、匹配准确性及 fallback 处理。

直接读取 document.documentElement.lang
这是最简单也最可靠的方式,document.documentElement 指向 HTML 根元素,它的 lang 属性值就是页面声明的语言。浏览器原生支持,无需 DOM 查询或正则匹配。
常见错误是误用 document.querySelector('html').getAttribute('lang')——虽然也能工作,但多一次查询,且当 HTML 元素未加载完成时可能返回 null;而 document.documentElement 在脚本执行时始终存在(哪怕 DOM 未就绪)。
- 在
中同步脚本里用它,能拿到初始lang值(如) - 如果页面后续通过 JavaScript 修改了
document.documentElement.lang = 'en',这个属性也会实时反映新值 - 若 HTML 标签没写
lang,该属性返回空字符串'',不是undefined或null
用 getAttribute() 从 元素获取(需确保 DOM 就绪)
当你必须显式查标签(比如调试渲染前的 HTML 字符串),或者脚本在 里但依赖 querySelector 逻辑时,得注意执行时机。
典型翻车点:脚本放在 且没加 defer,直接调 document.querySelector('html').getAttribute('lang') 可能报错 Cannot read property 'getAttribute' of null,因为此时 虽存在,但 querySelector 在某些旧浏览器中可能不稳定。
- 安全做法是包裹在
DOMContentLoaded事件里,或使用document.addEventListener('DOMContentLoaded', ...) - 也可以改用
document.documentElement.getAttribute('lang'),它不依赖querySelector,更轻量 - 注意:如果服务端渲染时用了占位符(如
),而模板未被正确替换,这里会读到原始字符串,比如"{{lang}}"
从 HTML 字符串中提取(服务端/预渲染场景)
如果你处理的是原始 HTML 字符串(比如 SSR 输出、爬虫抓取内容、单元测试 mock),不能依赖 document 对象,就得用正则或 DOMParser。
别用模糊正则如 /lang\s*=\s*["']([^"']*)["']/i——它可能匹配到 <meta name="language" content="..."> 或内联 SVG 的属性,造成误判。
- 推荐用
DOMParser解析后取根元素:const doc = new DOMParser().parseFromString(htmlString, 'text/html');<br>const lang = doc.documentElement.lang || '';
- 若环境不支持
DOMParser(如某些 Node.js 版本),可用更严格的正则:/]*lang\s*=\s*["']([^"']*)["']/i,并只取第一个匹配 - 注意大小写:HTML 规范允许
LANG、Lang等写法,正则必须加i标志
lang 属性为空或无效时的 fallback 处理
不少页面漏写 lang,或写成 lang="default" 这类非法值。W3C 推荐用 und(undetermined)表示未知语言,但实际极少见到。
单纯判断 lang === '' 不够——有些框架(如 Next.js)会在 hydrate 前把 lang 清空,导致短暂为 '',但之后才补上。
- 业务中建议 fallback 到
navigator.language或navigator.languages[0],但注意它们反映的是浏览器设置,未必等于页面语言 - 服务端渲染时,应由后端注入真实语言标识,前端只负责读取,避免用客户端信息覆盖服务端决策
- 如果做国际化检测,别只信
lang属性——还要检查<meta http-equiv="content-language">(已废弃但仍有遗留)、Accept-Language请求头(服务端可用)
真正麻烦的不是怎么取值,而是 lang 属性常被忽略、误设、或动态覆盖后没同步更新相关 i18n 状态。读取后最好立刻存入应用状态,并监听 document.documentElement 的 attrmodified 类似行为(需 MutationObserver 模拟),否则容易出现语言切换了但 aria-label 没变的问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











