多语言资源需通过asset()生成cdn路径并配置app.asset_host为完整https地址,cdn须启用accept-language作为缓存键,禁用html_cache_on,伪静态路由需避免后缀缓存污染,语言json响应头cache-control设为max-age=3600。

多语言资源本身不走 CDN 缓存,但它的加载路径、静态文件(如语言包 JSON)、以及伪静态路由生成的 URL 都会受 CDN 影响。直接配 CDN 不解决多语言切换问题,反而容易因缓存导致语言错乱。
多语言 JS/JSON 文件必须走 asset() + CDN 配置
ThinkPHP 的多语言前端通常用 lang.js 或按语言拆分的 zh-CN.json、en-US.json 等文件。这些文件若放在 public/static/lang/ 下,模板里写死 /static/lang/zh-CN.json,CDN 就无法识别或回源失败。
- 必须统一用
{:asset('lang/zh-CN.json')}生成路径,否则 CDN 域名不会生效 -
app.asset_host必须配置为完整 HTTPS 地址,例如https://cdn.example.com,不能只写cdn.example.com - 确保 CDN 回源路径设为
/public(阿里云需带尾部斜杠,腾讯云建议不带),否则请求https://cdn.example.com/static/lang/zh-CN.json会 404 - 语言 JSON 文件要设响应头
Cache-Control: public, max-age=3600,但不要设太长(比如 1 年),否则改了语言内容用户看不到更新
伪静态路由开启后,多语言参数会被缓存污染
比如你用 Route::get('news/:id', 'News/read')->lang('zh'),再配了 url_html_suffix => 'html',最终生成 /news/123.html。CDN 若对 *.html 缓存 1 天,用户切到英文时,CDN 仍返回中文版 HTML —— 因为 URL 没变,缓存没区分语言维度。
- 所有带多语言切换的页面,禁止对
*.html或通用后缀做全量缓存 - CDN 缓存规则要加「缓存键包含语言头」:启用
Accept-Language作为缓存键的一部分(阿里云叫「自定义缓存键」,腾讯云叫「缓存参数」) - 如果 CDN 不支持多维缓存键,就别用伪静态后缀,改用 query 参数,例如
/news/123?lang=en,并在 CDN 规则中显式包含lang参数 - ThinkPHP 的
Request::header('accept-language')可用于服务端 fallback,但不能替代 CDN 层的语言感知
多语言模板片段不能被静态缓存(HTML_CACHE_ON)
开启 HTML_CACHE_ON 后,ThinkPHP 会把整个 HTML 输出写成 .shtml 文件。一旦用户访问过中文页,CDN 或服务器缓存了 /about.shtml,后续英文请求也拿到中文内容 —— 因为静态缓存不识别语言上下文。
- 只要用了多语言,
HTML_CACHE_ON必须设为false,哪怕只在部分页面用 - 如果非要缓存,只能退回到「动态缓存」,用
Cache::tag('lang_zh')->set(...)分语言前缀存数据,再由模板动态拼装 - 千万别在
HTML_CACHE_RULES里写'*'=>[...]这种全局规则,它会无差别覆盖所有语言分支 - 检查
HTML_PATH目录权限,避免因写入失败导致降级成空缓存,反而掩盖语言逻辑错误
最易忽略的一点:CDN 缓存键默认不含 Cookie 和 Header,而 ThinkPHP 多语言常依赖 think_lang Cookie 或 X-Lang 自定义头。不显式配置缓存键维度,等于把多语言功能交给运气。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











