手记

`fetch`和`XMLHttpRequest`有什么区别?

大家好!在做一项有趣的项目时,我有个念头,来聊聊fetchXMLHTTPRequest的区别。虽然这个问题有点不准确,但了解了它的创建历史后,你仍然需要知道它。作为一名开发者,我在日常处理各种API时,了解这些可以避免写不必要的代码,这是很有用的。

📖 什么是XMLHTTPRequest:简介

在 JavaScript 中,XMLHttpRequest 对象用于与服务器进行交互。你可以从 URL 中获取数据而无需进行完整的页面刷新。这使得网页可以更新部分而不打扰用户当前的操作。简单来说,它是一个 API。一提到这个,我们就会想到事件循环、异步(代码执行将在一段时间后完成)等概念。例如,使用 XMLHTTPRequest 的代码可能如下所示:

    const xhr = new XMLHttpRequest();
    // 方法, URL, [是否异步, 用户名, 密码]
    xhr.open("GET", "/api/getPage");
    // 请求数据
    xhr.send()

进入全屏模式,退出全屏模式

XMLHTTPRequest的创建历史让我们回溯到了恐龙时代的遥远年代……好了,开个玩笑。事实上,这个API最初是由微软开发的,并且首次在微软Exchange Server 2000软件中的Outlook Web组件中引入。

当时它被称作不同的名字——IXMLHTTPRequest,在最初的接口版本中,它与现在有些不同,如果这样说的话。也就是说,基础显然是保留了下来,但很明显,在这25年里进行了调整。后来,它被添加到了MSXML 2.0中,再后来,在1999年3月被添加到Internet Explorer 5中。

然后,Mozilla 的程序员基于 IXMLHTTPRequest 开发了自己的版本,称为 nsIXMLHttpRequest,并通过我们熟悉的 XMLHttpRequest 访问。所有这些功能在 2000 年 12 月的 Gecko 版本 0.6 中添加(Gecko 是用于 FireFox 和许多其他地方的浏览器引擎)。当时 Web 开发还处于起步阶段,因为 FireFox 的第一个版本是在 2002 年 9 月发布,最初被称为 Phoenix,然后是 FireBird,直到 2004 年才被称为 FireFox。在此之前,有 Netscape Navigator,但它与 Internet Explorer 的竞争,但这又是另一个故事了,这里没有必要详述。后来,Safari、Opera 和其他浏览器也增加了支持。所以当别人告诉你这个对象是为了兼容旧浏览器时,他们说得没错,因为这可以追溯到 90 年代末,当时 Web 开发还处于起步阶段。你甚至可以回想起互联网泡沫时期,但诚然,那可能更早一些,或者如果是 Internet Explorer 的话,那就是那个时候。

👀 那有什么不一样?

所以,回到关于差异的问题,最重要的差异其实隐藏在历史里,因为 XMLHTTPRequest 仅仅是一个老但仍然支持的 API,而 fetch 则是一个新的 API,几乎取代了它。截至今天,XMLHTTPRequest 2.0 于 2012 年 1 月 发布,但 1.0 标准的最新版本则是在同年 12 月 发布。这便是当前的标准。但试想那些一直在写这些代码的开发者的表情:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', '/api/getData', true);

    xhr.onload = function () {
        if (xhr.status >= 200 && xhr.status < 300) {
            var data = JSON.parse(xhr.responseText);
            console.log(data);
        } else {
            console.error('请求成功,但状态码不在正常范围内:', xhr.status);
        }
    };

    xhr.onerror = function () {
        console.error('发生网络错误。');
    };

    xhr.send();

全屏模式, 退出全屏

而不是这个

    fetch('/api/getData')
        .then(response => {
            if (!response.ok) {
                throw new Error('网络响应不成功');
            }
            return response.json();
        })
        .then(data => {
            console.log('获取的数据为:', data);
        })
        .catch(error => {
            console.error('在fetch操作中出现了问题:', error);
        });

全屏 退出全屏

几年前,这是唯一立刻想到的事情。

但认真说来,这里有一份简短的差异列表:

  1. 基于承诺的特性: Fetch API 采用承诺机制,这使得处理异步代码变得更容易,并让你可以方便地使用 .then()asyncawait 这些便捷语法。

  2. 简化界面: Fetch API 使用起来更简单,语法也更直观。例如,发起请求时,您无需创建对象并配置其属性,不像 XHR 那样需要。

  3. 支持新特性: Fetch API 支持 Request 和 Response 对象等新特性,提供了处理请求和响应及其转换的便捷方式。

  4. 支持流处理: Fetch API 支持流式数据处理,可以让你在接收到数据的同时进行处理,从而能够处理大量数据。

  5. 取消请求: 尽管 Fetch API 没有内置取消请求的功能,但可以通过使用 AbortController 来实现这一点,从而使请求管理更加灵活。

  6. 改进的自定义功能: Fetch API 提供了更多的配置选项,例如设置请求头、缓存模式和其他参数。

  7. cors支持: Fetch API 提供了更灵活的 CORS(跨源资源共享)处理方式,从而可以更灵活地配置跨域资源请求。

  8. 更好的错误处理能力: 当你使用 Fetch API 时,可以更好地处理响应状态,因为请求错误(例如网络不可用)会拒绝这个承诺,而如果是 4xx 或 5xx 状态码的成功响应,则不会拒绝这个承诺,你需要自己检查状态码。

这当然不是本人——只是张挺酷的照片。

当然,还有很多不同之处,但我认为现在没有必要一一列举这些差异,因为从各个方面来说,这显然是为满足现代浏览器需求而对旧标准进行了改进和优化。

erset 后记

起初,我想简单地写一句,说fetch是较新的标准,但这有点太简单了,没有提供太多信息。实际上有很多酷炫的内容值得探讨。甚至可以单写一篇文章来探讨fetch,但这篇文章没有特别强调这一点。不过,总的来说,我觉得问题不大。

……

如果你喜欢这篇文章,你可以给作者点赞来支持作者,该项目是开源的HMPL模板语言项目。谢谢!❤️

💎 星HMPL ★

非常感谢您读了这篇文!


[OOP]:面向对象编程
[CRUD]:增删改查
[JVM]:Java虚拟机
[SUT]:测试系统

0人推荐
随时随地看视频
慕课网APP