网络请求

网络请求

fetch和xhr的区别

FetchXMLHttpRequest(XHR)都是用于在浏览器中发起网络请求的工具,但它们在设计、使用方式和特性上有许多区别。以下是它们的主要区别:

1. 设计和语法

  • XMLHttpRequest (XHR)
    • 设计:较早出现,主要用于实现 AJAX(Asynchronous JavaScript and XML)功能,允许网页在不重新加载页面的情况下与服务器交互。
    • 语法:较为复杂,需要手动设置请求方法、URL、回调函数等。
    • 示例代码
      1
      2
      3
      4
      5
      6
      7
      8
      var xhr = new XMLHttpRequest();
      xhr.open('GET', 'https://example.com/data', true);
      xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
      console.log(xhr.responseText);
      }
      };
      xhr.send();
  • Fetch
    • 设计:是现代的网络请求接口,基于 Promises 设计,语法更简洁,更符合现代 JavaScript 的编程习惯。
    • 语法:使用 Promise,支持链式调用,代码更简洁。
    • 示例代码
      1
      2
      3
      4
      fetch('https://example.com/data')
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error('Error:', error));

2. 返回值

  • XMLHttpRequest
    • 返回值是一个 XMLHttpRequest 对象,通过 onreadystatechange 事件和 readyState 属性来处理响应。
    • 需要手动检查 readyStatestatus 来判断请求是否成功。
  • Fetch
    • 返回值是一个 Promise,直接返回响应对象。
    • 使用 .then().catch() 来处理成功和失败的情况,更符合现代异步编程模式。

3. 错误处理

  • XMLHttpRequest
    • 错误处理较为复杂,需要在 onreadystatechange 中检查 statusstatusText
    • 网络错误(如请求超时、网络中断等)可能不会触发 onreadystatechange
  • Fetch
    • 错误处理更简单,通过 .catch() 捕获网络错误。
    • 但需要注意,fetch 只会在网络错误时触发 .catch(),如果服务器返回 HTTP 错误状态码(如 404、500),需要手动检查 response.okresponse.status

4. 功能支持

  • XMLHttpRequest
    • 支持同步请求(async = false),但不推荐使用,因为会阻塞主线程。
    • 支持多种请求方法(GET、POST、PUT、DELETE 等)和多种响应格式(如 JSON、XML、文本等)。
  • Fetch
    • 默认只支持异步请求,无法实现同步请求。
    • 支持多种请求方法和响应格式,但语法更简洁,例如通过 response.json()response.text() 等方法直接解析响应内容。
    • 支持更现代的特性,如 CORS(跨域资源共享)预检请求、请求头和响应头的处理等。

5. 兼容性

  • XMLHttpRequest
    • 兼容性较好,几乎所有现代浏览器和较旧浏览器都支持。
  • Fetch
    • 在较新的浏览器中广泛支持,但在一些较旧的浏览器(如 IE)中可能需要使用 polyfill(如 whatwg-fetch)来兼容。

6. 使用场景

  • XMLHttpRequest
    • 适用于需要对请求和响应进行精细控制的场景,例如需要处理进度事件、上传文件等。
  • Fetch
    • 适用于大多数现代的网络请求场景,尤其是需要简洁代码和现代异步编程支持的场景。

总结

  • 如果你正在开发一个现代的 Web 应用,并且需要简洁的语法和现代的异步编程支持,建议使用 Fetch
  • 如果你需要兼容较旧的浏览器,或者需要对请求和响应进行更精细的控制(如同步请求、进度事件等),可以使用 XMLHttpRequest