Javascript中fetch函数的使用示例,怎样正确使用fetch
fetch
函数使用示例,涵盖了常见的场景,如 GET 请求、POST 请求、处理响应、错误处理以及使用 async/await
。
fetch()
是现代 JavaScript 中用于发起网络请求(例如从服务器获取数据)的标准方式。它返回一个 Promise,使得处理异步操作更加方便。
基本结构
fetch(resource, options)
.then(response => {
// 处理初始的 Response 对象
// 这个对象包含了响应的状态码、头部等信息,但还没有实际的数据体
if (!response.ok) { // 检查 HTTP 状态码是否表示成功 (200-299)
throw new Error(`HTTP error! Status: ${response.status}`);
}
// 需要调用 .json(), .text(), .blob() 等方法来解析响应体,这些方法也返回 Promise
return response.json(); // 假设我们期望得到 JSON 数据
})
.then(data => {
// 处理最终解析出来的数据
console.log('成功获取数据:', data);
})
.catch(error => {
// 处理请求过程中的任何错误(网络错误、解析错误、上面抛出的 HTTP 错误)
console.error('请求失败:', error);
});
示例 1:简单的 GET 请求 (获取 JSON 数据)
假设我们要从一个公开的 API (如 JSONPlaceholder) 获取一篇文章的数据。
const apiUrl = 'https://jsonplaceholder.typicode.com/posts/1';
console.log('开始发起 GET 请求...');
fetch(apiUrl) // 默认是 GET 请求,所以 options 参数可以省略
.then(response => {
console.log('收到响应:', response); // 打印 Response 对象本身
// 检查 HTTP 状态码
if (!response.ok) {
// 如果状态码不是 2xx,则抛出错误,会被下面的 .catch() 捕获
// 例如,如果 URL 错误导致 404 Not Found
throw new Error(`HTTP 错误! 状态码: ${response.status}`);
}
// 响应状态 OK,解析 JSON 数据体
// response.json() 返回一个新的 Promise
console.log('响应状态 OK,开始解析 JSON...');
return response.json();
})
.then(postData => {
// 这个 .then 处理的是 response.json() 返回的 Promise
console.log('成功解析 JSON 数据:', postData);
// 在这里使用获取到的数据,例如更新页面内容
document.getElementById('output').textContent = `标题: ${postData.title}\n内容: ${postData.body}`;
})
.catch(error => {
// 统一处理错误:可能是网络连接问题,也可能是上面抛出的 HTTP 状态错误
console.error('GET 请求过程中发生错误:', error);
document.getElementById('output').textContent = `获取数据失败: ${error.message}`;
});
示例 2:POST 请求 (发送 JSON 数据)
假设我们要向服务器发送一个新的文章数据。
const postApiUrl = 'https://jsonplaceholder.typicode.com/posts'; // API 端点接受 POST 请求
const newPost = {
title: '我的新文章标题',
body: '这是文章的内容...',
userId: 5 // 假设是用户 ID 5 创建的
};
console.log('开始发起 POST 请求...');
fetch(postApiUrl, {
method: 'POST', // 明确指定请求方法为 POST
headers: {
// 告诉服务器我们发送的是 JSON 格式的数据
'Content-Type': 'application/json',
// 如果 API 需要认证,可能还需要添加 Authorization 头
// 'Authorization': 'Bearer YOUR_API_TOKEN'
},
// 请求体:需要将 JavaScript 对象转换为 JSON 字符串
body: JSON.stringify(newPost)
})
.then(response => {
console.log('收到 POST 响应:', response);
if (!response.ok) { // 检查状态码,例如 201 Created 通常表示成功
// 处理可能的错误,如 400 Bad Request, 500 Internal Server Error
throw new Error(`HTTP 错误! 状态码: ${response.status} ${response.statusText}`);
}
// 即使是 POST 请求成功,服务器也可能返回一些数据(例如创建后的资源 ID)
// JSONPlaceholder 在 POST 成功后会返回包含 id 的对象
return response.json();
})
.then(responseData => {
console.log('POST 请求成功,服务器返回:', responseData);
// 通常服务器会返回创建的资源的 ID
document.getElementById('output').textContent = `文章创建成功! 新 ID: ${responseData.id}`;
})
.catch(error => {
console.error('POST 请求过程中发生错误:', error);
document.getElementById('output').textContent = `创建文章失败: ${error.message}`;
});
示例 3:使用 async/await
语法 (推荐)
async/await
使得异步代码看起来更像同步代码,更易于阅读和理解。它只是 Promise 的语法糖。
const apiUrl = 'https://jsonplaceholder.typicode.com/users/1'; // 获取用户信息
// 定义一个异步函数
async function fetchUserData() {
console.log('使用 async/await 发起 GET 请求...');
try {
// 使用 await 等待 fetch Promise 完成,得到 Response 对象
const response = await fetch(apiUrl);
console.log('收到响应 (async/await):', response);
// 检查状态码
if (!response.ok) {
throw new Error(`HTTP 错误! 状态码: ${response.status}`);
}
// 使用 await 等待 .json() Promise 完成,得到最终数据
console.log('响应状态 OK,开始解析 JSON (async/await)...');
const userData = await response.json();
// 处理数据
console.log('成功获取并解析用户数据 (async/await):', userData);
document.getElementById('output').textContent = `用户名: ${userData.username}\n邮箱: ${userData.email}`;
} catch (error) {
// 使用 try...catch 捕获所有错误
console.error('请求失败 (async/await):', error);
document.getElementById('output').textContent = `获取用户数据失败: ${error.message}`;
}
}
// 调用异步函数
fetchUserData();
// --- async/await 用于 POST ---
async function postDataAsync(url, data) {
console.log('使用 async/await 发起 POST 请求...');
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
console.log('收到 POST 响应 (async/await):', response);
if (!response.ok) {
throw new Error(`HTTP 错误! 状态码: ${response.status} ${response.statusText}`);
}
const responseData = await response.json();
console.log('POST 成功 (async/await),服务器返回:', responseData);
// ... 处理成功逻辑 ...
return responseData; // 可以返回结果
} catch (error) {
console.error('POST 请求失败 (async/await):', error);
// ... 处理错误逻辑 ...
throw error; // 可以重新抛出错误,让调用者知道
}
}
// 调用 POST 的异步函数
// const newPostData = { title: 'Async Post', body: 'Content', userId: 1 };
// postDataAsync('https://jsonplaceholder.typicode.com/posts', newPostData)
// .then(result => console.log("Async POST 调用完成:", result))
// .catch(err => console.log("Async POST 调用出错"));
示例 4:处理不同的响应类型 (如文本)
有时 API 返回的不是 JSON,而是纯文本。
// 假设这个 URL 返回纯文本 "OK" 或错误信息
const textApiUrl = 'https://httpbin.org/robots.txt'; // 这个 URL 返回文本
console.log('开始获取文本数据...');
fetch(textApiUrl)
.then(response => {
console.log('收到文本响应:', response);
if (!response.ok) {
throw new Error(`HTTP 错误! 状态码: ${response.status}`);
}
// 使用 response.text() 来解析文本数据
console.log('响应状态 OK,开始解析文本...');
return response.text();
})
.then(textData => {
console.log('成功获取文本数据:');
console.log(textData);
document.getElementById('output').textContent = `收到的文本内容:\n${textData.substring(0, 100)}...`; // 显示部分内容
})
.catch(error => {
console.error('获取文本数据失败:', error);
document.getElementById('output').textContent = `获取文本失败: ${error.message}`;
});
// 其他可能的解析方法:
// response.blob() // 处理二进制文件,如图片
// response.formData() // 处理 FormData 响应
// response.arrayBuffer() // 处理通用的、固定长度的原始二进制数据
发表回复