在 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 具有以下特點:。

  • 基於回呼函數(Callback)的設計 可用如 onreadystatechange 等回呼函數監控請求的完成或進度。
  • 監控狀態碼與 readyState 可通過 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)
異步處理 使用 Promise 簡單明瞭 需要回調函數
錯誤處理 通過 .catch() 管理 檢查 readyState 狀態
進度事件 不支援 通過 onprogress 處理
跨域支援 自動支援 CORS 支援 CORS
瀏覽器支援 不支援 IE11 和更舊版本 與舊版瀏覽器相容
控制的粒度 簡單直觀 允許進行細粒度控制

總結

  • Fetch API 提供基於 Promise 的簡單靈活的 HTTP 請求,並在現代瀏覽器中被推薦使用。

您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。

YouTube Video