如何在苏州吃到伦敦的下午茶?CDN全解析

Ying2026-05-28tech网络

前情提要

起因

我在看Vue3文档时,有一段内容:“你可以借助 script 标签直接通过 CDN 来使用 Vue,这里我们使用了 unpkg,但你也可以使用任何提供 npm 包服务的 CDN,例如 jsdelivr 或 cdnjs。当然,你也可以下载此文件并自行提供服务。通过 CDN 使用 Vue 时,不涉及“构建步骤”。这使得设置更加简单,并且可以用于增强静态的 HTML 或与后端框架集成。但是,你将无法使用单文件组件 (SFC) 语法。”

果然能把一段文字说的如此官方和绕口的肯定是技术文档了(内心os),大白话就是Vue提供两种使用范式:

无构建步骤的 CDN 全局脚本方式(script标签引入,简单,面向增强静态页);

基于 npm + 构建工具(Vite / Vue CLI / webpack)的单文件组件工程方式(强大,面向复杂应用)。

Vue中为什么CDN不能用SFC?

SFC是Vue中的单文件组件,也就是项目中常用的.vue文件。本质原因是浏览器不认识.vue文件。

浏览器如何认识?需要Vue的编译器(@vue/compiler-sfc) 把它拆成JS渲染函数、CSS、模版逻辑,这个编译过程就是构建的一部分。

回归到<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>这个代码中,它表达的就是官方文档中“借助script标签通过CDN来使用Vue……这里我们使用了unpkg……”

这里的CDN就是CDN提供的服务,详细如下个部分。

CDN:让苏州人吃到伦敦下午茶的服务

一个有趣的设想

翻开百度百科,对CDN(Content Delivery Network 内容分发网络)有着专业的解释,这里我不多写。我要写的是前端开发需要掌握的部分:

“它是部署在各地的边缘服务器集群,通过智能DNS解析把用户请求导向最近的节点。它的核心四件套:分布式储存、负载均衡、请求重定向、内容管理。 对前端来说,CDN让静态资源离用户更近,减少网络延迟,降低源站压力。”

如果让它更好理解一点,我有个好玩的设想,我在伦敦开了一家下午茶餐厅,没有分店,名字叫“美味Vue”,招牌下午茶是vue.global.js ,远在苏州的顾客想吃这道菜,如果我没有CDN服务的场景:

  • 苏州顾客打开浏览器线上点餐,请求全球外卖员必须去伦敦取菜;
  • 网络距离远,关卡多,网络延迟高,可能等好久;
  • 顾客多的时候就像大学时代学生抢课,服务器崩溃。

作为老板的我当然高瞻远瞩,引入CDN服务,决定在全球各地开分店,纽约、东京、北京都预先做好招牌下午茶(相当于把vue.global.js 文件缓存到了各地)。

分布式储存 —— 各地分店都备好货

我的招牌下午茶不只在伦敦,而是复制并存储到全球成百上千个节点(分店)

负载均衡 —— 分店客流均匀分配

如果伦敦总店突然涌入大批顾客订购,系统会自动把一部分请求分散给巴黎、阿姆斯特丹的分店处理

网络请求的重定向 —— 智能派单到顾客最近的店

苏州顾客点单,后台系统不会把请求发到伦敦,而是距离最近的北京,通过DNS重定向,用户无感知,但吃的是本地货

内容管理 —— 招牌下午茶的更新与保质期管理

当我更新了Vue版本,相当于更新了菜单,不能让其他分店再卖过期下午茶。CDN需要一套内容管理机制,设定缓存时间(如7天向总店确认一次),也支持主动刷新(purge)全球分店的存货,让它们立刻去伦敦总店拉最新版的下午茶。

CDN如何构建全球分店?

这是我对CDN物理基础和商业模式的好奇,我想知道CDN是如何构建“全球店铺”,这个店铺会不会卖其他东西。

全球CDN节点就是物理上部署在不同城市的服务器, 不是虚拟概念。

比如 Cloudflare,它在全球 100 多个国家、超过 330 个城市有节点。每个节点可能是一排机架,里面有服务器、硬盘、网线,就放在当地某个数据中心里,甚至直接放在电信运营商的机房内部。 Akamai 更是号称“最深的边缘”,把服务器直接塞进了几千个本地网络(比如某个小区的宽带机房附近)。

这些都要烧很多钱。这些巨头每年在服务器、带宽、场地上的支出是天文数字。

一个CDN绝对不可能只为一个人的Vue.js服务,它是超级美食广场。如果每家想用 CDN 的网站,都得自己去伦敦、纽约、新加坡租机房、买服务器、雇运维,那除了 Netflix、Google 这种巨头,别人根本用不起,Vue 的作者也不可能去全球布点。

那么,“下午茶店”能不能只卖下午茶?当然,也能卖别的。这取决于这个CDN的场景:

  • 专门化的CDN:像 unpkg、jsdelivr、cdnjs,它们就是“前端库专卖店”。它们只服务 npm 包和 JS/CSS 库,但底层的物理服务器,依然是那个什么都卖的“美食广场”提供的。
  • 通用 CDN:你自己如果做了一个完整的网站(比如一个Vue构建的单页应用),也可以直接使用阿里云 CDN、腾讯云 CDN 或 Cloudflare 的通用加速服务。

延伸:VPN和CDN的关系

两者没有直接关系,但都依赖同一个物理基础:遍布全球的服务器网络。翻墙用的 VPN/代理服务,本质就是在世界各国租用或部署真实的服务器,安装 VPN 服务端软件。

只不过VPN需要目的是隐藏身份、加密传输,或突破访问限制,下午茶私密沙龙。

前端开发中的CDN

基础概念和原理

🙋🏻Q:什么是CDN?它是怎么加速的?

  • CDN是部署在各地的边缘集群服务器,通过DNS智能解析把用户请求拉近最近的节点。
  • 命中缓存则返回,不命中则回源站拉取。
  • 核心四件套:分布式储存、负载均衡、请求重定向、内容管理。
  • 对前端来说,CDN 让静态资源离用户更近,减少网络延迟,降低源站压力。

前端性能优化中的CDN

1.资源部署策略 🙋🏻Q:静态资源如何上传CDN?

  • webpack的publicPath,构建时把资源路径改成CDN名,如https://cdn.example.com/assets/
  • 文件哈希名,vue.abc123.js,内容不变哈希就不变,永久缓存也不怕更新。
  • html不缓存或协商缓存,JS/CSS做永久强缓存(Cache-Control: max-age=31536000)。

2.域名拆分和域名收敛 🙋🏻Q:为什么以前要用多个 CDN 域名,现在又建议用少的?

  • 以前是HTTP1.1协议,要求浏览器对同一域名的并发连接限制,如Chrome最多6个,多域名可以突破限制,加快加载。
  • 现在HTTP2.0支持多路复用,单域名并发不再是瓶颈,多域名反而增加DNS查询和连接建立成本,所以推荐域名收敛

3.预解析和预连接 🙋🏻Q:写的页面里有CDN引用的字体,怎么让它更快?

  • <link rel="dns-prefetch" href="//cdn.example.com">:提前把CDN域名解析成IP。
  • <link rel="preconnect" href="//cdn.example.com">:更彻底,提前建立TCP连接+TLS握手。
  • 用于页面关键渲染路径上、但要稍后才加载的资源。

4.通过 CDN 外链还是打包进 bundle? 🙋🏻Q:像 Vue/React,你是挂 CDN 的 <script>标签还是 npm 装包?

  • CDN外链:利用公共CDN(unpkg/jsdelivr),用户可能已缓存,加载块;但不支持构建、不参与tree shaking,无法用SFC。适合演示、后台无构建步骤的小页面。
  • 打包进项目:经过webpack/vite构建,能tree shaking、代码压缩、模块化管理,适合正式项目。
  • 折中方案:通过externals配置让第三方库走CDN加载,但又当作模块引入,比如通过webpack配置externals配Vue。

缓存策略与文件更新

这里考察的是前端对强缓存和CDN的理解。

🙋🏻Q:CDN上的文件怎么更新?如何保证用户拿到的是最新版?

🙋🏻A:

  • 文件名哈希是根本解决方案。 内容变,文件名就变,视为全新资源。旧文件的强缓存实效对用户无影响。
  • HTML文件入口不设强缓存。 每次都向服务器请求确认,保证拿到的index.html里指向的是最新的JS/CSS。
  • CDN的缓存刷新。如果文件名不能用哈希且必须更新,可以在CDN后台做purge/刷新,强制所有节点回源。但一般不推荐文件走CDN。

⚠️注意:

  • 可能存在覆盖式更新风险:如果同一个文件名先后对应两个内容,CDN节点可能缓存不一致,造成用户访问故障。所以文件名必须哈希相关;
  • CDN 缓存策略有两个控制入口:源站的 Cache-Control 头,和 CDN 控制台的缓存规则。通常 CDN 手动配置的优先级更高,所以我们在生产环境一般会在 CDN 后台为 HTML 设置不缓存,而为带哈希的静态资源设置长期缓存,这样无论源站头是否完善,CDN 都能正确执行我们的缓存意图。(CDN 缓存规则的决定权归属问题)

CDN的安全与可靠性

1.HTTPS与CDN 🙋🏻Q:CDN怎么配HTTPS?证书怎么办?

  • CDN服务商通常提供免费托管证书一键上传;
  • 前端需要注意:若CDN域名与主站不同,可能会涉及到跨域限制,需要CDN返回合适的CORS头(Access-Control-Allow-Origin);
  • 全站HTTPS时,CDN上的资源也必须HTTPS,避免混合内容警告。

2.SRI(子资源完整性) 🙋🏻Q:通过CDN public引入的库,怎么防止被篡改?

  • 使用 <script integrity="sha384-..." crossorigin="anonymous">,浏览器会比对哈希,不匹配就拒绝执行。
  • 前端要知道如何生成 SRI 哈希(工具或在线服务),以及这主要是防 CDN 被攻击篡改,并非防 XSS。

3.降级与容错 🙋🏻Q:CDN 挂了,页面怎么兜底?

  • 对于关键的 JS/CSS,可以在 CDN 加载失败后,动态创建 <script> 标签加载本地备份。
  • 例如监听 <script> 的 onerror,fallback 到自有服务器的资源。
  • 可以利用 Service Worker 做更优雅的离线策略。

Webpack/Vite 构建层面的 CDN 配置(工程化考点)

🙋🏻Q: “在 Vue/React 项目里,你是怎么把产物部署到 CDN 的?”

🙋🏻A:

  • 设置output.publicPath或Vite的base为CDN地址。
  • 生产环境构建出带哈希的文件,手动或通过CI/CD上传到CDN源站,再由CDN分发。
  • 如果是npm库作者,要清楚怎么把自己的包通过unpkg/jsdelivr 提供 CDN 访问。
  • 结合之前的SFC限制,知道通过CDN外链Vue不能用单文件组件。
Last Updated 5/29/2026, 12:02:58 PM