阿里云主机折上折
  • 微信号
Current Site:Index > Comparison between Fetch API and XMLHttpRequest

Comparison between Fetch API and XMLHttpRequest

Author:Chuan Chen 阅读数:65155人阅读 分类: HTML

Basic Concepts of Fetch API and XMLHttpRequest

The Fetch API is a modern browser standard designed to replace the traditional XMLHttpRequest (XHR) for network requests. It is based on Promises, offering a more concise and intuitive syntax. XMLHttpRequest, on the other hand, is an earlier browser API that, while powerful, is more complex to use. Both can perform HTTP requests but differ significantly in implementation and features.

// Basic usage of Fetch API
fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

// Basic usage of XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.onload = function() {
  if (xhr.status === 200) {
    console.log(JSON.parse(xhr.responseText));
  }
};
xhr.send();

Syntax and User Experience

The Fetch API uses chained Promise calls, resulting in flatter code structures. Error handling is unified through catch and supports the async/await syntax. XMLHttpRequest requires callback configuration, which can lead to "callback hell."

// Fetch with async/await
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Fetch failed:', error);
  }
}

// XHR with event listeners
const xhr = new XMLHttpRequest();
xhr.addEventListener('load', handleLoad);
xhr.addEventListener('error', handleError);
xhr.open('GET', 'https://api.example.com/data');
xhr.send();

function handleLoad() { /*...*/ }
function handleError() { /*...*/ }

Request and Response Handling

The Fetch API's Response object provides rich methods:

  • response.json() for JSON parsing
  • response.text() for text
  • response.blob() for binary data
  • response.formData() for form data

XMLHttpRequest requires manual response type handling:

xhr.responseType = 'json'; // or 'text', 'arraybuffer', etc.
xhr.onload = function() {
  console.log(xhr.response); // Automatically parsed based on responseType
};

Error Handling Mechanisms

Fetch only rejects on network failures; HTTP error statuses (e.g., 404) do not trigger catch. Additional checks like response.ok or status are required. XMLHttpRequest directly checks the status property for request states.

// Fetch error handling
fetch('https://api.example.com/404')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .catch(error => console.log('Error:', error.message));

// XHR error handling
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4) {
    if (xhr.status >= 200 && xhr.status < 300) {
      console.log(xhr.response);
    } else {
      console.error('Request failed with status:', xhr.status);
    }
  }
};

Request Control and Timeouts

XMLHttpRequest natively supports the timeout property, while Fetch requires AbortController for timeout control:

// Fetch timeout control
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);

fetch('https://api.example.com/slow', {
  signal: controller.signal
})
  .then(response => {
    clearTimeout(timeoutId);
    return response.json();
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Request timed out');
    }
  });

// XHR timeout setting
xhr.timeout = 5000;
xhr.ontimeout = function() {
  console.log('Request timed out');
};

Request Progress Monitoring

XMLHttpRequest provides progress events:

xhr.upload.onprogress = function(event) {
  console.log(`Uploaded ${event.loaded} of ${event.total} bytes`);
};
xhr.onprogress = function(event) {
  console.log(`Downloaded ${event.loaded} of ${event.total} bytes`);
};

Fetch API currently lacks native progress APIs but can simulate it via streaming:

const response = await fetch('https://api.example.com/large-file');
const reader = response.body.getReader();
let receivedLength = 0;

while(true) {
  const {done, value} = await reader.read();
  if (done) break;
  receivedLength += value.length;
  console.log(`Received ${receivedLength} bytes`);
}

Cross-Origin Request Handling

Both follow the same-origin policy, but Fetch's CORS mode is more explicit:

fetch('https://api.example.com/data', {
  mode: 'cors',
  credentials: 'include' // Include cookies
});

XMLHttpRequest requires the withCredentials property:

xhr.withCredentials = true;

Browser Compatibility

XMLHttpRequest is compatible with all modern browsers, including IE6. Fetch API is unsupported in IE but widely implemented in modern browsers. Polyfills can address compatibility:

<script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.6.2/dist/fetch.umd.min.js"></script>

Performance Comparison

For simple requests, performance differences are minimal. For high concurrency, Fetch may have a slight edge due to its lighter Promise-based implementation. XMLHttpRequest excels in fine-grained request control.

Advanced Feature Comparison

Fetch API supports Service Worker request interception:

// In a Service Worker
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

XMLHttpRequest supports synchronous requests (blocks UI thread):

xhr.open('GET', 'https://api.example.com/data', false); // Synchronous
xhr.send();
if (xhr.status === 200) {
  console.log(xhr.responseText);
}

Practical Application Scenarios

For simple REST API calls, prefer Fetch API. Choose XMLHttpRequest for upload progress monitoring or legacy browser support. Modern libraries like axios encapsulate both, offering a unified interface.

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.