Ajax 之战:XMLHttpRequest 与 Fetch API

Ajax 是大多数 web 应用程序背后的核心技术,它允许页面向 web 服务发出异步请求,因此数据可以不经过页面往返服务器无刷新显示数据 。
术语 Ajax 不是一种技术,相反,它指的是从客户端脚本加载服务器数据的方法 。多年来已经引入了几种选择,目前有两种主要方法,大多数 JAVAScript 框架使用其中一种或两种 。
在本文中,我们将研究早期 XMLHttpRequest 和现代 Fetch 的优缺点,以确定哪种 Ajax API 最适合你的应用 。
XMLHttpRequest
XMLHttpRequest 在 1999 年首次作为非标准的 Internet Explorer 5.0 ActiveX 组件出现,微软开发它是为了支持基于浏览器的 Outlook 版本,XML 是当时最流行(或被宣扬)的数据格式,除此之外,XMLHttpRequest 还支持文本和尚未发明的 JSON 。
Jesse James Garrett 在他 2005 年的文章《AJAX: Web 应用程序的新方法》中提出了“AJAX”概念,那时谷歌邮箱和谷歌地图等基于 AJAX 的应用程序已经存在,但是这个术语激励了开发人员,并引起了流畅的 Web 2.0 体验爆炸式增长 。
AJAX 是“Asynchronous JavaScript and XML”的缩写,尽管严格地说,开发人员并不需要使用异步方法、JavaScript 或 XML 。我们现在将通用的“Ajax”术语表示任何从服务器获取数据、更新 DOM 而无需刷新整个页面的客户端过程 。
所有主流浏览器都支持 XMLHttpRequest,并在 2006 年成为官方的 web 标准 。下面是一个简单的例子,从你的域 / 服务 / 端点获取数据,然后在控制台将 JSON 结果显示为文本:
const xhr = new XMLHttpRequest();xhr.open("GET", "/service");// state change eventxhr.onreadystatechange = () => {// is request complete?if (xhr.readyState !== 4) return;if (xhr.status === 200) {// request successfulconsole.log(JSON.parse(xhr.responseText));} else {// request not successfulconsole.log("HTTP error", xhr.status, xhr.statusText);}};// start requestxhr.send();onreadystatechange 回调函数在请求的生命周期中运行好几次;XMLHttpRequest 对象的 readyState 属性则返回当前状态:

  • 0 (uninitialized) - 请求未初始化
  • 1(loading)- 服务器连接建立
  • 2(loaded)- 请求收到
  • 3(interactive)- 处理请求
  • 4(complete)- 请求完成,响应准备就绪
在达到状态 4 之前,几个函数就可以做很多事情 。
Fetch
Fetch 是一个现代基于 promise 的 Ajax 请求 API,首次出现于 2015 年,在大多数浏览器中都得到了支持 。它不是基于 XMLHttpRequest 构建的,并且用更简洁的语法提供了更好的一致性 。下面的 Promise 链函数与上面的 XMLHttpRequest 例子相同:
fetch("/service", { method: "GET" }).then((res) => res.json()).then((json) => console.log(json)).catch((err) => console.error("error:", err));或者你可以使用 async/await:
try {const res = await fetch("/service", { method: "GET" }),json = await res.json();console.log(json);} catch (err) {console.error("error:", err);}Fetch 更清晰、更简洁,并且经常在 Service worker 中使用 。
开源会话重播
OpenReplay 是 FullStory 和 LogRocket 的开源替代品,它通过回放用户在你的应用程序上的一切操作,并显示每个问题的操作堆栈,提供完整的可观察性 。OpenReplay 是自托管的,可以完全控制你的数据 。
Ajax 之战:XMLHttpRequest 与 Fetch API

文章插图
 
快乐调试吧!现代的前端团队 —— 开始自由地监控你的 web 应用程序 。
第 1 回合:Fetch 获胜
与陈旧的 XMLHttpRequest 相比,Fetch API 除了具有更清晰简洁的语法之外,还有其它几个优势 。
头、请求和响应对象
上面简单 fetch() 示例中,使用一个字符串定义 URL 端点,也可以传递一个可配置的 Request 对象,它提供了有关调用的一系列属性:
const request = new Request("/service", { method: "POST" });console.log(request.url);console.log(request.method);console.log(request.credentials);// FormData representation of bodyconst fd = await request.formData();// clone requestconst req2 = request.clone();const res = await fetch(request);Response 对象提供了对访问所有详细信息的类似访问:
console.log(res.ok); // true/falseconsole.log(res.status); // HTTP statusconsole.log(res.url);const json = await res.json(); // parses body as JSONconst text = await res.text(); // parses body as textconst fd = await res.formData(); // FormData representation of body


推荐阅读