JavaScript 中的 Fetch/XMLHttpRequest

JavaScript 中的 Fetch/XMLHttpRequest

本文对 JavaScript 中的 Fetch/XMLHttpRequest 进行了说明。

YouTube Video

javascript-html-fetch-xhr.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-html-fetch-xhr.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-html-fetch-xhr.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-html-fetch-xhr.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

JavaScript 中的 Fetch/XMLHttpRequest

JavaScript 中的 FetchXMLHttpRequest(XHR)都用于发送 HTTP 请求和从服务器检索数据。

Fetch API

Fetch API 是一种用于处理 HTTP 请求的现代方法,被设计为 XHR 的后续技术。它是一个基于 Promise 的异步 API,允许更简单和灵活的请求处理。

用法

 1fetch('http://127.0.0.1:3000/example.json')
 2    .then((response) => {
 3        if (!response.ok) {
 4            throw new Error('HTTP error: ' + response.status);
 5        }
 6        return response.json();  // Parse the response as JSON
 7    })
 8    .then((data) => {
 9        console.log(data);  // Use the fetched data
10        console.log(JSON.stringify(data));
11    })
12    .catch((error) => {
13        console.error('An error occurred:', error);  // Error handling
14    });
  • 此代码使用Fetch API向指定的URL发送GET请求,将响应处理为JSON,并显示结果或输出错误信息。

功能

Fetch API具有以下特点:。

  • 基于Promise 异步操作可以通过Promise进行管理,使代码更加简洁易读。
  • 易于错误处理 可以通过catch块轻松处理错误。
  • 可以使用如response.json()这样的方法进行解析 响应数据可以方便地以JSON或文本格式处理。
  • 支持CORS Fetch遵循跨域资源共享(CORS)规则运行。
  • 请求配置灵活 不仅支持GET/POST,还可以轻松配置如PUT和DELETE等HTTP方法。

示例:POST 请求

 1fetch('http://127.0.0.1:3000/example.json', {
 2        method: 'POST',
 3        headers: {
 4            'Content-Type': 'application/json'
 5        },
 6        body: JSON.stringify({ name: 'Alice', age: 25 })  // Send the request body as JSON
 7    })
 8    .then(response => response.json())
 9    .then(data => console.log(JSON.stringify(data)))
10    .catch(error => console.error('Error:', error));
  • 此代码发送包含JSON数据的POST请求,并以JSON格式接收并显示服务器响应。

缺点

Fetch API存在以下缺点:。

  • 浏览器兼容性 旧版浏览器(特别是IE11)不支持Fetch API
  • 难以进行精细控制 与XHR相比,不适合处理进度事件等低级控制。

XMLHttpRequest(XHR)

XMLHttpRequest 是一种长期用于处理 HTTP 请求的 API 并被广泛用作 AJAX(异步 JavaScript 和 XML)的基础。支持异步通信,可以在不重新加载整个页面的情况下从服务器检索数据。

用法

 1const xhr = new XMLHttpRequest();
 2xhr.open('GET', 'http://127.0.0.1:3000/example.json', true);
 3xhr.onreadystatechange = function() {
 4    if (xhr.readyState === 4 && xhr.status === 200) {
 5        const data = JSON.parse(xhr.responseText);  // Parse the response as JSON
 6        console.log(data);  // Use the data
 7        console.log(JSON.stringify(data));
 8    }
 9};
10xhr.send();  // Send the request
  • 此代码使用XMLHttpRequest发送GET请求,解析收到的JSON响应并显示。

功能

XMLHttpRequest具有以下特点:。

  • 基于回调函数 使用如onreadystatechange等回调函数来监控请求的完成或进度。
  • 监控状态码和就绪状态 可以通过xhr.readyStatexhr.status检查请求状态。
  • 兼容性广泛 即使在旧版浏览器上也能工作。
  • 可监控请求进度 可以通过如xhr.upload.onprogress等事件监控进度。

示例:POST 请求

 1const xhr = new XMLHttpRequest();
 2xhr.open('POST', 'http://127.0.0.1:3000/example.json', true);
 3xhr.setRequestHeader('Content-Type', 'application/json');
 4xhr.onreadystatechange = function() {
 5    if (xhr.readyState === 4 && xhr.status === 200) {
 6        const data = JSON.parse(xhr.responseText);
 7        console.log(data);
 8        console.log(JSON.stringify(data));
 9    }
10};
11xhr.send(JSON.stringify({ name: 'Alice', age: 25 }));  // Send the data
  • 此代码使用XMLHttpRequest发送包含JSON数据的POST请求,接收响应并显示。

缺点

XMLHttpRequest存在以下缺点:。

  • 代码复杂度高 使用回调函数管理异步处理往往较为复杂。
  • 不支持原生Promise 由于默认不支持Promise,异步处理显得比较繁琐。

Fetch APIXMLHttpRequest 的比较

功能 Fetch API XMLHttpRequest (XHR)
异步处理 使用 Promises 简单 需要回调函数
错误处理 使用 .catch() 处理方便 检查 readyState 状态
进度事件 不支持 使用 onprogress 处理
跨域支持 自动支持 CORS 支持 CORS
浏览器支持 不支持 IE11 及更早版本 兼容旧版浏览器
控制的粒度 简单直观 允许细粒度控制

总结

  • Fetch API 提供基于 Promises 的简单灵活的 HTTP 请求,推荐在现代浏览器中使用。

您可以在我们的YouTube频道上使用Visual Studio Code跟随上述文章进行学习。 请也查看我们的YouTube频道。

YouTube Video