要让 asset() 输出 CDN 地址,需在 .env 中设置 ASSET_URL=https://cdn.example.com(末尾无斜杠),并运行 php artisan config:clear;mix() 需单独配置 MIX_ASSET_URL 或 Vite 的 base;CDN 路径须与 public 目录结构完全一致;Debugbar 静态资源需通过 DEBUGBAR_ROUTE_PREFIX 单独配置。

asset() 函数默认不走 CDN,必须显式配置 ASSET_URL 环境变量,否则所有 asset('css/app.css') 依然输出主站地址。
怎么让 asset() 输出 CDN 地址
关键就一条:改 .env,加 ASSET_URL=https://cdn.example.com(注意末尾不能有斜杠)。
-
ASSET_URL必须是纯协议+域名,比如https://cdn.example.com或//cdn.example.com;带路径会拼错,ASSET_URL=https://cdn.example.com/static会导致asset('css/app.css')变成https://cdn.example.com/static/css/app.css,而你 CDN 实际只放了/css/app.css,结果 404 -
APP_URL保持原样(如https://yoursite.com),它不影响asset()的输出 - 改完必须运行
php artisan config:clear,否则缓存会掩盖变更
mix() 和 asset() 别混着用,它们读的环境变量不同
如果你用 Laravel Mix 或 Vite 打包资源,mix() 默认不看 ASSET_URL,它有自己的规则:
- Laravel Mix:优先读
MIX_ASSET_URL环境变量;若没设,就 fallback 到本地路径。不能只配ASSET_URL就指望mix()走 CDN - Vite:在
vite.config.js里设base,例如base: process.env.APP_ENV === 'production' ? 'https://cdn.example.com/' : '/';同时确保.env里有MIX_ASSET_URL=https://cdn.example.com(Vite 插件部分逻辑会读它) - 混用风险高:比如 Blade 里
asset('css/app.css')走 CDN,但mix('css/app.css')还走本地,页面加载一半资源失败
CDN 文件结构必须和 public 目录完全一致
CDN 不是“随便扔上去就行”,它依赖路径映射:
- 你本地
public/css/app.css,上传后必须是https://cdn.example.com/css/app.css,不能是https://cdn.example.com/assets/css/app.css或https://cdn.example.com/public/css/app.css - 上传工具(如
aws s3 sync、rclone、七牛qshell)要指定源路径为public/,目标路径为 CDN 根目录,避免多套一层前缀 - 如果 CDN 强制要求子路径(如
/static/),那就得重写asset()辅助函数,或在视图中硬编码https://cdn.example.com/static/{{ $path }},别硬扛配置
Debugbar 的静态资源也要单独配
Debugbar 默认从 _debugbar 路由加载 JS/CSS,不受 ASSET_URL 控制:
- 修改
config/debugbar.php中的route_prefix配置项,设为env('DEBUGBAR_ROUTE_PREFIX', 'https://cdn.example.com/_debugbar') - 在
.env加DEBUGBAR_ROUTE_PREFIX=https://cdn.example.com/_debugbar - 顺手关掉
include_vendors(设为false),避免 CDN 已提供 jQuery 却又从本地再加载一遍
最易忽略的是 ASSET_URL 和 MIX_ASSET_URL 的分离,以及 Debugbar 的独立配置——这三个地方漏一个,就会出现部分资源走 CDN、部分仍回源的现象,监控 Network 面板时容易误判为缓存问题。


















