JSON 与 HTTP
通过 HTTP 获取 JSON 数据
Section titled “通过 HTTP 获取 JSON 数据”JSON 的主要用途之一是从 Web 服务器 (API) 获取数据,并在网页或应用程序中使用这些数据。
本章演示了如何使用 JavaScript 中现代的 fetch API 来请求和处理 JSON 数据。
使用 Fetch API
Section titled “使用 Fetch API”fetch API 提供了一种现代、强大且灵活的接口来获取资源,包括从 API 获取 JSON 数据。它使用 Promise,使得异步操作更容易管理,特别是在结合 async/await 语法时。
示例:获取并显示菜单数据
Section titled “示例:获取并显示菜单数据”假设您的服务器上有一个名为 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>- 发起 Fetch:
fetch(menuUrl)会向指定的 URL 发起网络请求。它返回一个 Promise。 - 检查响应状态:
response.ok检查 HTTP 状态码是否表示成功 (例如,200-299)。如果不成功,则抛出错误。 - 解析 JSON:
response.json()读取完整的响应流,并将主体文本解析为 JSON。它也返回一个 Promise,该 Promise 在解析出结果的 JavaScript 对象或数组后解析。 - 处理数据:
displayMenu函数接收解析后的 JavaScript 数组 (menuItems),清除加载消息,并动态创建 HTML 元素 (一个包含<li>和<a>元素的<ul>列表) 来显示菜单。 - 错误处理:
try...catch块确保捕获并记录在 fetch 过程中发生的任何错误 (网络错误、无效 JSON 等),并向用户显示错误消息。
为什么使用 fetch 而不是 XMLHttpRequest?
- 基于 Promise: 使异步操作的处理更清晰,尤其是在结合
async/await使用时。 - 更灵活: 提供更强大、更灵活的功能集 (例如,更容易处理请求头、请求/响应主体)。
- 现代标准: 它是目前浏览器中发起网络请求的标准。
关于 Fetch API 的更多详细信息,请参阅 MDN Web Docs: Fetch API。