Angular 5部署Varnish代理后静态资源加载失败问题排查
我之前也碰到过几乎一模一样的Angular 5 + Varnish反向代理的坑,给你几个关键的调整点,应该能彻底解决你的问题:
你现在的问题根源之一是本地开发和代理环境的base href冲突:硬改index.html里的<base href="/albert/">会导致本地直接访问时资源路径错误,而代理环境又需要这个前缀来匹配Varnish的路由。
解决办法是用Angular CLI的启动参数来动态配置,不用硬改index.html:
临时启动时用命令:
ng serve --base-href=/albert/ --serve-path=/--base-href=/albert/:设置页面的base标签值,让代理环境下的资源路径自动带上/albert/前缀--serve-path=/:让ng-serve在根路径提供服务,这样Varnish转发过来的请求能正确匹配后端资源
如果想永久配置,修改
angular.json里的serve选项:
找到projects -> [你的项目名] -> architect -> serve -> options,添加以下配置:"baseHref": "/albert/", "servePath": "/"这样每次启动ng-serve都会自动应用这些参数,不用手动输入。
现在Varnish只是把https://test.corporate.com/albert/反向代理到http://dev5.local:4200/,但请求里的/albert前缀没有被移除,导致ng-serve收到的请求是/albert/inline.bundle.js,而它在根路径提供服务,自然找不到这个资源。
你需要在VCL配置里添加路径重写规则,把/albert前缀去掉后再转发到后端:
vcl 4.0; backend dev5 { .host = "dev5.local"; .port = "4200"; } sub vcl_recv { # 匹配所有以/albert开头的请求 if (req.url ~ "^/albert(/.*)?$") { # 移除/albert前缀,保留后面的路径(如果有的话) set req.url = regsub(req.url, "^/albert", ""); # 如果移除后路径为空,设置为根路径 if (req.url == "") { set req.url = "/"; } # 转发到dev5后端 set req.backend_hint = dev5; } }
这个配置会把https://test.corporate.com/albert/inline.bundle.js转换成http://dev5.local:4200/inline.bundle.js转发给ng-serve,后端就能正确返回资源了。
配置完成后,按以下步骤验证:
- 访问
https://test.corporate.com/albert/,打开浏览器开发者工具的网络面板,检查静态资源的请求路径:应该是https://test.corporate.com/albert/inline.bundle.js,且状态码为200 - 本地直接访问
http://dev5.local:4200/albert/,同样检查资源路径,应该能正常加载所有静态文件
内容的提问来源于stack exchange,提问作者Albert Hendriks

