1.3 Ajax 与传统 Web 请求的区别


1.3 Ajax 与传统 Web 请求的区别

本节摘要:传统 Web 请求以"文档"为单位——任何交互都导致浏览器卸载当前文档、请求新文档、重新渲染整页;Ajax 以"数据"为单位——浏览器保留当前文档,JavaScript 后台取回数据并局部修改。本节用一次"点赞"操作在两种模式下的完整旅程做逐帧对照,量化传输、渲染、状态保持的差异,并说明这场变革如何重塑了前后端分工。

问题现场:一次点赞,两种命运

同一个功能,两套代码,用户的感受天差地别。

页面是一个图文详情页:顶部一张大图,中间三千字的文章,底部一排点赞、收藏、分享按钮,用户已经读到了文章中部。此刻他点了"赞"。

传统模式的旅程:点赞按钮是一个链接或表单提交,浏览器发起导航请求。当前页面被卸载——此刻意味着文章里正在播放的什么都会中断、滚动位置被丢弃。服务器把"点赞数加一"写入数据库,然后重新渲染整张详情页的 HTML 返回。浏览器解析新文档、加载资源(有缓存则快些)、重建 DOM、重排版重绘。用户最终看到点赞图标亮了,但视口弹回了页面顶部,刚才读到的那一段得重新滚回去找。他心里骂了一句,读书的心气断了。

Ajax 模式的旅程:点击按钮,JavaScript 拦截默认行为,向服务器发一个小请求。服务器只做一件事——点赞数加一,返回 {"likes": 1025} 这样十几个字节。页面从头到尾没有被卸载,滚动位置原封不动,响应回来后脚本把按钮旁边那个数字元素的文本换成 1025、给按钮加个高亮样式,结束。整个过程用户甚至没有感知到网络往返。

差别不在"快慢",在交互的单位。传统模式里,浏览器眼中每次交互都是"要一份新文档";Ajax 模式里,交互只是"交换一份数据"。这个单位的降级,带来后面所有量化的差异。

两种请求模式对照图

传统整页刷新与 Ajax 局部更新对照

传统整页刷新与 Ajax 局部更新对照

一、逐层量化:差别到底有多大

对比不能停在"体验更好"这种形容词上,要拆成可度量的维度。

**传输维度。**假设详情页 HTML 120 KB(含内联结构与脚本引用),一次传统点赞要把这 120 KB 全部重传(哪怕有缓存,协商请求至少也要一个往返);Ajax 模式传输的是约 20 字节的 JSON,加 HTTP 头也就几百字节,压缩后更小。对高频交互(点赞、收藏、轮询状态)累积起来,是数十倍到数百倍的流量差。移动端弱网环境下,这个差距直接体现在用户等待时长上。

**渲染维度。**整页刷新要重走完整渲染管线:解析 HTML 构建 DOM、解析 CSS 计算 style、生成布局树、绘制合成,中间还有脚本执行可能反复触发重排。局部更新只改一个文本节点,浏览器只需对受影响的小区域重绘。两者的 CPU 开销不在一个数量级——这也是低端手机上整页刷新明显卡顿、局部更新依然顺滑的原因。

**状态维度。**这是最容易被忽略、却最伤害体验的一项。页面卸载会带走一切运行时状态:滚动位置、未提交的表单草稿、展开的折叠面板、播放中的媒体、正在进行的选择操作。传统模式下"保住状态"需要服务端把状态编码进新页面的 URL 或表单里,成本高且极易遗漏;Ajax 模式中文档根本没动,状态天然保全。

**服务器维度。**传统模式下每次交互都要服务端执行完整模板渲染;Ajax 模式下服务端只序列化一份数据,没有模板开销。更重要的是职责变化:服务器从"页面工厂"变成"数据服务"——同一个接口可以喂网页、喂手机端、喂第三方调用者,复用价值完全不同。

维度 传统整页请求 Ajax 请求
交互单位 文档 数据
典型传输量 整页 HTML(几十 KB 起) JSON(字节级到 KB 级)
页面状态 卸载重建,全部丢失 保留,滚动输入均在
渲染成本 完整渲染管线 单区域重绘
服务器职责 渲染 HTML 页面 输出数据接口
可缓存性 页面级 接口级,粒度更细
失败影响 错误页替换整个页面 可局部提示并恢复
接口复用 几乎不可复用 网页、移动端、第三方共用

二、两段代码的直接对照

用最小可运行的例子感受两种模式。传统模式下点赞是一个链接(也可以是表单),浏览器导航:

<!-- 传统:一次点击等于一次页面跳转 --> <a href="/article/42/like">点赞 (1024)</a>

服务器端渲染框架接到这个请求,写入数据库,然后重定向或直接重新渲染详情页模板。前端代码只有一行,代价是交互单位是整页。

Ajax 模式下,按钮承担一次完整的小型数据流:

// Ajax:拦截默认行为 换成一份数据交换 const btn = document.querySelector('#like-btn'); const count = document.querySelector('#like-count'); btn.addEventListener('click', async () => { btn.disabled = true; // 防重复点击 try { const res = await fetch('/api/articles/42/like', { method: 'POST' }); if (!res.ok) throw new Error('HTTP ' + res.status); const data = await res.json(); // { likes: 1025 } count.textContent = data.likes; // 只改这一个数字 btn.classList.add('liked'); // 只改这一个样式 } catch (err) { showToast('点赞失败,请稍后再试'); // 失败原地恢复 不炸页面 } finally { btn.disabled = false; } });

代码量多了几倍,换来的是:页面不动、状态保全、失败可原地恢复。注意这段代码里已经埋了第 3 章要展开的主题——防重复提交、错误分类、界面状态恢复。传统模式下这些要么做不了,要么要用整页跳转这种重伤才能实现。

还要注意两段代码里服务器的角色差异:前者需要一个"渲染详情页"的完整模板流程;后者只需要一个纯数据接口,返回值连 HTML 都不含。同一个业务动作,服务器端的工作形状完全不同。

三、架构连锁反应:前后端的重新分工

技术差异积累到一定程度会改变架构。Ajax 普及之后,前后端的分工线从"页面的哪里"移到了"数据的两头":

传统架构(服务端渲染):后端掌管路由、业务、模板渲染,前端工程师在模板里填标签,浏览器只是显示终端。优点是首屏快、对客户端要求低;缺点是每次交互都动用整页渲染,前后端代码耦合在同一模板里,无法独立演进。

分离架构(接口加前端渲染):后端只提供 JSON 接口与业务逻辑,前端接管路由与全部渲染。交互不再依赖整页跳转,一个应用可以只加载一次骨架。代价也真实存在:首屏需要先取数据再渲染(有白屏窗口,需要加载态设计)、接口需要设计版本与文档、跨域与鉴权成为必答题。

现实工程里两者经常混用:内容展示页(文章、商品详情)用服务端渲染保证首屏与检索友好,交互密集区(评论、点赞、购物车)用 Ajax。判断标准不是流行度,而是这个区域的交互频率与状态保持需求——交互越频繁、状态越要保,越该走 Ajax。

💡 一个判断口诀:改"一小块、很频繁"的交互用 Ajax;"整页换内容、低频"的跳转用导航。点赞用 Ajax,翻到另一篇文章用导航,中间地带(比如列表分页)看状态保持需求。

四、Ajax 不是免费午餐:代价清单

讲差异不能只报喜。Ajax 模式把复杂度从前端挪走了一部分,又搬进来另一部分:

  • 首屏时序复杂化:数据到达前页面是空的,需要设计加载态、骨架屏,否则用户面对空白比面对白屏更茫然。
  • 错误处理责任转移:传统模式下服务器错误页兜底一切;Ajax 下每个请求的失败都要前端自己接住,漏接就是"点了没反应"。
  • 调试链路变长:问题可能出在事件绑定、请求构造、网络、服务端、解析、渲染任一环,需要开发者工具的网络面板配合定位。
  • 书签与分享:传统模式每个状态对应一个 URL;纯 Ajax 更新不改变地址栏,用户没法把"筛选后的列表"存成书签——这正是后来前端路由要解决的问题。
  • 搜索引擎可见性:早期爬虫不执行脚本,纯 Ajax 内容可能不被收录。服务端渲染与混合渲染方案很大程度上就是为补这个短板而生。

这些代价不是否定 Ajax,而是提醒:选它是因为交互单位匹配,不是因为它是先进名词。把低频的整页内容切换硬做成 Ajax,只会白付复杂度。

常见疑问解答

表单提交算传统请求还是 Ajax

取决于有没有被拦截。原生表单提交(不阻止默认行为)就是传统请求,会导航;用 JavaScript 接管 submit 事件、改成 fetch 发送,就是 Ajax。同一个表单两种命运,3.2 节专门做这个改造。

Ajax 请求会出现在浏览器历史记录里吗

不会。Ajax 不产生导航,不写入历史栈。这也是上一条"书签问题"的根源。需要让某种状态可前进后退时,要配合前端路由主动往历史栈里压记录。

全用 Ajax 的单页应用一定比传统网站好吗

不一定。内容型网站(新闻、文档)用户要的是"最快看到正文",服务端渲染往往更合适;工具型、交互型应用(编辑器、后台、社交流)才真正受益于 Ajax 与 SPA。架构选择的第一性问题永远是用户的使用方式。

本节要点回顾

  • 核心区别是交互单位:传统模式以文档为单位,任何交互整页重来;Ajax 以数据为单位,文档保留、局部修改。
  • 量化差异:传输量从整页 HTML 降到字节级 JSON;渲染从完整管线降到单区域重绘;页面状态从清零变为天然保全。
  • 服务器角色改变:从页面工厂变为数据服务,接口由此具备跨端复用价值,这是前后端分离的技术起点。
  • 选择标准:小范围、高频、要保状态的交互用 Ajax;整页、低频的内容切换用导航,不要为了"先进"硬上。
  • 代价要认账:加载态、错误处理、调试链路、书签与检索可见性,都是 Ajax 模式必须额外支付的工程成本。

一张速查决策卡

把本节的判断标准浓缩成一张可以贴在工位上的决策卡。面对"这个交互该不该用 Ajax"时,依次回答三个问题:改动范围小于页面三分之一吗?操作频率高吗(一天多次而非一次)?页面状态(滚动、输入、展开态)需要保持吗?三个"是",坚定用 Ajax;三个"否",坚定用导航;中间地带按权重取舍——状态保持的需求权重最高,因为它是传统模式最难补、Ajax 模式免费送的一项。

再补一个团队协作视角:模式选择也是沟通成本的选择。整页刷新模式下,前后端讨论的是"页面长什么样";Ajax 模式下,讨论的是"接口契约长什么样"(2.4 节的主题)。契约讨论前期更费劲(要定义结构、错误码、边界情况),但一旦定型,两端可以并行开发、独立演进——这笔前期投入换来的是后期变更成本的大幅下降。反之,用整页模式躲开契约讨论的团队,往往在项目中期被"改一个字段要动两端、发两次版"的摩擦力拖住。选择交互模式,某种意义上也是在选择团队的协作结构。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U