前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

Webapi:XMLHttpRequest是怎么实现的|浏览器篇

# Webapi:XMLHttpRequest是怎么实现的

30 秒速记

  • XMLHttpRequest 让页面通过接口获取服务器数据,再局部修改 DOM,无需因一条数据变化而刷新整个页面。
  • 它把 JavaScript、浏览器网络能力和页面更新连接起来,是理解浏览器 WebAPI 工作方式的典型入口。
  • 网络操作不能只按普通函数调用理解:请求结果需要通过回调在后续时机交还给页面逻辑。
  • 理解其机制前要区分同步回调与异步回调,因为两者进入执行流程的时间和所处任务不同。
  • 该能力提高了局部更新效率,但请求过程还会涉及 HTTP、浏览器进程协作及安全限制。

XMLHttpRequest 本质上是浏览器提供给 JavaScript 的网络能力,用来异步请求服务器数据并局部更新页面。 调用 open 和 send 后,请求交给浏览器的网络模块处理,当前调用栈不会一直等待。响应到达后,状态变化会形成后续任务,事件循环再触发 load、error 等回调,业务代码随后解析数据并修改 DOM。工程中还要检查 status 和响应内容,因为 404 通常也会进入 load,而网络失败、超时和 CORS 限制需要分别处理。

在上一篇文章中我们介绍了 setTimeout 是如何结合渲染进程的循环系统工作的,那本篇文章我们就继续介绍另外一种类型的 WebAPI——XMLHttpRequest。

自从网页中引入了 JavaScript,我们就可以操作 DOM 树中任意一个节点,例如隐藏 / 显示节点、改变颜色、获得或改变文本内容、为元素添加事件响应函数等等, 几乎可以“为所欲为”了。

不过在 XMLHttpRequest 出现之前,如果服务器数据有更新,依然需要重新刷新整个页面。而 XMLHttpRequest 提供了从 Web 服务器获取数据的能力,如果你想要更新某条数据,只需要通过 XMLHttpRequest 请求服务器提供的接口,就可以获取到服务器的数据,然后再操作 DOM 来更新页面内容,整个过程只需要更新网页的一部分就可以了,而不用像之前那样还得刷新整个页面,这样既有效率又不会打扰到用户。

关于 XMLHttpRequest,本来我是想一带而过的,后来发现这个 WebAPI 用于教学非常好。首先前面讲了那么网络内容,现在可以通过它把 HTTP 协议实践一遍;其次,XMLHttpRequest 是一个非常典型的 WebAPI,通过它来讲解浏览器是如何实现 WebAPI 的很合适,这对于你理解其他 WebAPI 也有非常大的帮助,同时在这个过程中我们还可以把一些安全问题给串起来。

但在深入讲解 XMLHttpRequest 之前,我们得先介绍下同步回调和异步回调这两个概念,这会帮助你更加深刻地理解 WebAPI 是怎么工作的

原理拆解: XMLHttpRequest 是渲染进程中暴露给 JavaScript 的浏览器能力。调用 open 和 send 后,请求交由浏览器网络相关模块处理;异步请求不会让当前 JavaScript 调用栈一直等待。响应状态变化会在后续时机形成任务,事件循环取出任务后调用 readystatechange、load、error 等监听器,页面逻辑再解析数据并修改 DOM。因此“发出请求”和“消费结果”分属不同执行时段。

最小验证: 输入是公开测试接口返回的 JSON;要验证的结论是异步请求先让当前脚本结束,随后才执行 load 回调。可在现代浏览器控制台直接运行:

const xhr = new XMLHttpRequest();

xhr.open("GET", "https://jsonplaceholder.typicode.com/todos/1", true);
xhr.responseType = "json";

xhr.addEventListener("load", () => {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log("response", xhr.response.title);
  } else {
    console.log("http error", xhr.status);
  }
});

xhr.addEventListener("error", () => {
  console.log("network error");
});

console.log("before send");
xhr.send();
console.log("after send");
@前端进阶之旅: 代码已经复制到剪贴板

关键参数 true 表示异步模式。预期先输出 before send、after send,请求成功后再输出 response。若离线、DNS 或连接失败会触发 error;服务器返回 404 通常仍进入 load,所以必须检查 status。若目标服务调整了跨域策略,浏览器也可能因 CORS 拒绝把响应交给脚本。

边界与排查: 同步 XMLHttpRequest 会阻塞执行线程,在主线程上会造成页面无法响应,现代工程不应依赖它。请求成功也不代表业务数据有效,仍需校验状态码、响应类型和字段。取消请求可使用 abort(),超时可设置 timeout 并监听 timeout。排查时结合网络面板检查请求头、响应头、状态码、耗时和预检请求,再用性能面板确认回调中是否存在大规模 DOM 更新或长任务;网络完成很快但界面仍卡顿时,瓶颈往往位于响应处理与渲染阶段。

面试官追问

追问 1库存页调用异步 xhr.send() 后,下一行立即读取 xhr.response.title,评审者认为局域网足够快所以不会为空,你怎么反驳?
参考回答

网络快也不能把异步请求变成同步执行,当前脚本会先继续运行,响应只能在后续的 load 等回调中消费。最小验证应先看到 before send、after send,再看到响应;立即读取存在时序错误。

追问 2商品列表每五秒刷新一次库存,只允许更新对应数字而不能整页闪烁,你会让 XMLHttpRequest 和页面代码分别承担什么职责?
参考回答

XMLHttpRequest 负责请求库存接口,并在异步回调中交付响应;页面代码校验结果后只修改对应的 DOM 节点。局部请求避免整页重载,但回调若批量执行大规模 DOM 更新,界面仍可能出现长任务和卡顿。

追问 3公开接口返回 404 时仍触发了 load,开发者因此把它当成请求成功并渲染 xhr.response,你会怎样修正?
参考回答

load 表示传输流程已经完成,不保证 HTTP 状态代表成功,404 通常也会进入该回调。应在其中检查 status 的成功区间,并继续校验响应类型和业务字段;网络失败才主要由 error 处理。

追问 4线上请求在开发机正常、用户浏览器却失败,控制台同时可能出现离线、DNS、连接或 CORS 信息,你会怎样缩小范围?
参考回答

先在网络面板核对请求是否发出、状态码、耗时、请求头、响应头和预检请求,再区分 error、timeout 与 HTTP 错误。若服务端有响应但脚本拿不到数据,应继续检查 CORS;不能只盯着页面更新代码。

追问 5搜索联想框连续输入会产生多次未完成请求,团队在“等待全部返回”和“取消旧请求”之间争论,你会如何选择?
参考回答

若旧结果已无展示价值,可对过期的 XMLHttpRequest 调用 abort(),并只消费当前查询对应的响应。这样能减少陈旧结果覆盖新结果的机会,但仍需在回调层校验请求身份;取消请求不能替代状态码和数据校验。

追问 6接口在网络面板中很快完成,但包含数百条数据的页面仍明显卡顿,你会把排查重点放在哪里?
参考回答

应转向响应解析、回调逻辑和渲染阶段,用性能面板检查是否出现大规模 DOM 更新或长任务。异步请求只是不让当前调用栈等待网络,并不保证后续处理轻量;数据量增大时,瓶颈可能完全位于主线程。

# 回调函数 VS 系统调用栈

30 秒速记

  • 回调函数是作为参数交给另一个函数、并由后者在约定时机调用的函数。
  • 同步回调在主函数返回前执行,因此仍处于当前任务及其调用上下文中。
  • 异步回调在主函数结束后执行,不继续占用原主函数的 JavaScript 调用栈。
  • 页面主线程按消息队列逐个处理任务;异步回调可以被封装为新任务追加到队列,也可以进入微任务队列。
  • 微任务在当前任务末尾处理,而普通异步任务需要等待主线程从消息队列取到它;两者的执行时机不同。
  • 浏览器还为每个任务维护由 Chromium 的 C++ 代码形成的系统调用栈,可通过 Performance 或 chrome://tracing/ 观察相关过程。

回调函数是作为参数传入其他函数,并在约定时机被调用的函数;系统调用栈则是浏览器执行任务时由 Chromium 的 C++ 代码维护的调用链。 同步回调在主函数返回前执行,仍处于当前任务和调用上下文;异步回调在主函数结束后执行,不再占用原来的 JavaScript 调用栈。异步回调既可能作为新任务进入消息队列,也可能进入微任务队列,在当前任务末尾执行。排查执行过程时,可以通过 Performance 或 chrome://tracing/ 观察任务及其内部子过程。

← Webapi:setTimeout是怎么实现的宏任务和微任务:不是所有的任务都是一个待遇 →

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础