整个过程遇到不少坑,遂做一记录,以飨读者,避免重复劳动。

1. 域名改造

CDN需要单独的域名,因此针对静态资源,通过Nginx反向代理到单独域名之下。但也因此,项目所有静态资源的引用地址全部要通过域名+路径的方式。

直接的解决方案是在打包的时候加上deploy-url参数(或在angular.json配置),但,此方案存在2个问题。

  1. 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.
  2. 除了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都尝试了,也尝试着用网上的各种解决方案,诸如:

nginxCopy code
  • 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;
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方式,因此,最终的完美的解决方案就是二者结合,同时配置。

 

至此,全部问题都完美解决,测试,通过……再次干杯![]~( ̄▽ ̄)~*