Skip to content

JSON 与 HTTP

JSON 的主要用途之一是从 Web 服务器 (API) 获取数据,并在网页或应用程序中使用这些数据。

本章演示了如何使用 JavaScript 中现代的 fetch API 来请求和处理 JSON 数据。

fetch API 提供了一种现代、强大且灵活的接口来获取资源,包括从 API 获取 JSON 数据。它使用 Promise,使得异步操作更容易管理,特别是在结合 async/await 语法时。

假设您的服务器上有一个名为 menu.json 的文件,内容如下:

[
{
"display": "JavaScript Basics",
"url": "/tutorials/javascript/basics"
},
{
"display": "HTML Fundamentals",
"url": "/tutorials/html/fundamentals"
},
{
"display": "CSS Styling",
"url": "/tutorials/css/styling"
}
]

您可以通过以下方式获取这些数据,并在您的网页上将其显示为链接列表:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON Fetch Example</title>
</head>
<body>
<h1>Tutorial Menu</h1>
<div id="menuContainer">Loading menu...</div>
<p id="errorContainer" style="color: red;"></p>
<script>
const menuContainer = document.getElementById('menuContainer');
const errorContainer = document.getElementById('errorContainer');
const menuUrl = 'menu.json'; // JSON 文件或 API 端点的路径
async function fetchMenu() {
try {
// 1. 使用 fetch 发起请求
const response = await fetch(menuUrl);
// 2. 检查响应状态是否正常 (例如,200)
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
// 3. 将响应主体解析为 JSON
// response.json() 返回一个 Promise,该 Promise 在解析完 JSON 数据后解析
const menuItems = await response.json();
// 4. 处理 JSON 数据 (显示它)
displayMenu(menuItems);
} catch (error) {
// 处理在 fetch 或解析过程中可能出现的任何错误
console.error('Failed to fetch menu:', error);
menuContainer.innerHTML = ''; // 清除加载消息
errorContainer.textContent = `Error loading menu: ${error.message}`;
}
}
function displayMenu(items) {
// 清除加载消息
menuContainer.innerHTML = '';
if (!Array.isArray(items)) {
errorContainer.textContent = 'Invalid menu data format.';
return;
}
// 创建列表元素
const ul = document.createElement('ul');
// 为每个菜单项创建列表项
items.forEach(item => {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = item.url;
a.textContent = item.display;
li.appendChild(a);
ul.appendChild(li);
});
// 将列表添加到容器中
menuContainer.appendChild(ul);
}
// 调用函数开始获取数据
fetchMenu();
</script>
</body>
</html>
  1. 发起 Fetch: fetch(menuUrl) 会向指定的 URL 发起网络请求。它返回一个 Promise。
  2. 检查响应状态: response.ok 检查 HTTP 状态码是否表示成功 (例如,200-299)。如果不成功,则抛出错误。
  3. 解析 JSON: response.json() 读取完整的响应流,并将主体文本解析为 JSON。它也返回一个 Promise,该 Promise 在解析出结果的 JavaScript 对象或数组后解析。
  4. 处理数据: displayMenu 函数接收解析后的 JavaScript 数组 (menuItems),清除加载消息,并动态创建 HTML 元素 (一个包含 <li> 和 <a> 元素的 <ul> 列表) 来显示菜单。
  5. 错误处理: try...catch 块确保捕获并记录在 fetch 过程中发生的任何错误 (网络错误、无效 JSON 等),并向用户显示错误消息。

为什么使用 fetch 而不是 XMLHttpRequest?

  • 基于 Promise: 使异步操作的处理更清晰,尤其是在结合 async/await 使用时。
  • 更灵活: 提供更强大、更灵活的功能集 (例如,更容易处理请求头、请求/响应主体)。
  • 现代标准: 它是目前浏览器中发起网络请求的标准。

关于 Fetch API 的更多详细信息,请参阅 MDN Web Docs: Fetch API。