yii框架通过配置assetbundle的baseurl实现cdn对接:生产环境设为cdn域名,开发环境保留@web;需同步配置前端构建工具base/publicpath、nginx缓存头,并禁用assetmanager本地发布。

Yii 框架本身不自动对接 CDN,但通过 AssetBundle 的 baseUrl 配置 + 构建时路径替换,就能让所有 CSS/JS/图片等静态资源请求直接打到 CDN 域名,无需改业务代码。
Yii2 中修改 AssetBundle 的 baseUrl 指向 CDN
这是最直接、最可控的方式。Yii2 的资源管理依赖 AssetBundle 类,而它的 baseUrl 属性决定了资源 URL 的前缀。只要在应用配置中统一覆盖这个值,所有注册的 AssetBundle 就会自动使用 CDN 地址。
在 config/web.php 的 components 下配置 assetManager:
'assetManager' => [
'bundles' => [],
'baseUrl' => YII_ENV_PROD ? 'https://static.example.com' : '@web',
],
注意:@web 是 Yii 默认的 Web 根路径别名,开发环境保留本地路径便于调试;生产环境强制走 CDN 域名。
- 必须确保
static.example.com已在 CDN 控制台完成接入,并正确回源到你的 Nginx 或 Web 服务器 - 如果部分 AssetBundle 显式设置了
baseUrl(比如第三方包硬编码了/assets/),需在bundles中单独覆盖,例如:'yii\web\YiiAsset' => ['baseUrl' => 'https://static.example.com'] - CDN 域名不能带路径后缀(如
https://static.example.com/cdn),否则会导致AssetBundle内部拼接出错
前端构建产物也要匹配 CDN 路径(Vite / Webpack)
仅改 Yii 配置还不够——如果你的项目是前后端分离架构(比如 Vue/React 前端独立部署),那么前端打包生成的 index.html 里引用的 JS/CSS,仍会指向相对路径或本地域名。这时必须在构建阶段注入 CDN 前缀。
Vite 项目修改 vite.config.ts:
base: process.env.NODE_ENV === 'production' ? 'https://static.example.com/' : '/',
Webpack(Vue CLI)项目修改 vue.config.js:
publicPath: process.env.NODE_ENV === 'production' ? 'https://static.example.com/' : '/',
- 这个
base或publicPath必须和 Yii 的baseUrl完全一致,否则页面加载时会出现混合资源(部分走 CDN,部分走源站) - 若使用哈希文件名(如
app.abc123.js),CDN 缓存可设为长期有效(Cache-Control: public, immutable),不用担心更新问题 - 不要用
rewrite在 Nginx 层做 302 跳转来“补救”路径错误——每次跳转会增加 100ms+ 延迟,且破坏浏览器缓存复用
CDN 回源与 Nginx 缓存头必须协同
CDN 不是魔法盒,它只是个中间缓存层。如果 Nginx 返回的响应头禁止缓存(比如 Cache-Control: no-store),或者没设 ETag/Last-Modified,CDN 就无法有效缓存,最终还是频繁回源。
在 Nginx 的静态资源 location 块中,至少要加这三行:
location ~* \.(js|css|png|jpg|webp|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header ETag "";
}
-
expires 1y和Cache-Control: public, immutable是强缓存组合,告诉 CDN 和浏览器“这文件一年内不会变”,可放心长期缓存 -
add_header ETag ""是关键:Yii 默认启用 ETag,但若你用了文件哈希命名(推荐),ETag 实际已无意义;清空它可避免 CDN 因 ETag 不一致而降级为协商缓存 - CDN 控制台中务必关闭「忽略源站缓存头」选项,否则 Nginx 配的
Cache-Control会被无视
最容易被忽略的是 AssetBundle 的发布行为:默认 assetManager 会把资源复制到 @web/assets/ 目录下再提供服务。如果你已将全部静态资源托管到 CDN,就该禁用本地发布,否则既浪费磁盘又可能因权限问题导致 403 —— 这需要在 assetManager 中显式设置 'forceCopy' => false 并确认所有资源确实已上传至 CDN 存储(如 OSS/COS)。











