整个过程遇到不少坑,遂做一记录,以飨读者,避免重复劳动。
1. 域名改造
CDN需要单独的域名,因此针对静态资源,通过Nginx反向代理到单独域名之下。但也因此,项目所有静态资源的引用地址全部要通过域名+路径的方式。
直接的解决方案是在打包的时候加上deploy-url
参数(或在angular.json
配置),但,此方案存在2个问题。
- Angular 13会提示:
Use "baseHref" option, "APP_BASE_HREF" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url.
- 除了JS、CSS等编译产生的文件之外,其他CSS、HTML中引用的assets文件路径还是基于
base-href
,也就是说,编译地不够彻底。
但直接通过base-href
更是存在问题。
各种搜索之下,死马当活马医,终于找到解决方案,参见:https://github.com/angular/angular-cli/pull/21537。也即,结合使用base
标签和provider
。
2. IP来源
部署上去之后,发现IP来源全部是SSR服务器IP,User-Agent
信息全是node。
于是,再次各种折腾、测试,包括各种header都尝试了,也尝试着用网上的各种解决方案,诸如:
- 1
- 2
- 3
- 4
set_real_ip_from x.x.x.x;
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
全都无效。
后来,脑门一拍,想通了,这些请求全部是SSR发起的服务端调用(类似Java的服务调用,并不是AJAX请求),并不是用户行为产生的。因此,直接判断并过滤此类请求即可。解决!┓( ´∀` )┏
3. CDN接入
接入过程无需详述,根据步骤顺序执行即可,有问题直接查看官方文档,或咨询技术支持。
4. gzip压缩
开启CDN后,发现源站开启的gzip并没有生效。
咨询技术支持后,等待了半天,得到回复:缺少Content-Length
头。再次,开启疯狂搜索模式……
得到的答案都是,动态gzip本来就没有Content-Length
头,只能通过hack方式绕道解决。
身为完美主义者的自己岂能接受这种别扭的方式?
继续搜……
终于,在一个角落,看到2个英文单词:static gzip
……参见:https://serverfault.com/questions/529621/forcing-nginx-to-send-content-length-headers-when-serving-static-files-with-gzip。
于是,搜索static gzip
解决方案,发现Angular已经取消了编译时的compress支持,只能通过gulp等任务手动开启。
再次完美解决![]~( ̄▽ ̄)~*
而这也解决了十多年前第一次搞网站时的疑惑,为啥各大站长工具都无法显示压缩比?
但,static gzip
方案仍然存在不足:对于动态的内容仍需要传统的dynamic gzip
方式,因此,最终的完美的解决方案就是二者结合,同时配置。
至此,全部问题都完美解决,测试,通过……再次干杯![]~( ̄▽ ̄)~*