Fetch API 是一组用于在 Web 浏览器中进行网络请求的现代 JavaScript API。它提供了一种更简洁、更强大的方式来处理网络请求,相比传统的 XMLHttpRequest 对象,Fetch API 更易于使用且功能更丰富。
特点
- 基于 Promise:Fetch API 是基于 Promise 的,这意味着你可以使用 Promise 的链式方法来处理异步操作,使代码更清晰易懂。
- 简洁的 API:Fetch API 提供了一组简洁的方法来执行各种类型的 HTTP 请求,包括 GET、POST、PUT、DELETE 等。
- 支持流式数据:Fetch API 支持读取和写入流式数据,这使得处理大型响应或请求时更加高效。
- 支持跨域请求:Fetch API 默认支持跨域请求,但在某些情况下可能需要额外配置以处理 CORS(跨域资源共享)。
基础使用
fetch() 函数发送了一个 GET 请求到指定的 URL,并返回一个 Promise 对象。使用 .then() 方法处理响应,并将其解析为 JSON 格式。如果请求失败或者响应状态码不在 200-299 范围内,将会抛出一个错误并通过 .catch() 方法捕获和处理。
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json(); // 将响应解析为 JSON 格式
})
.then(data => {
// 处理返回的数据
console.log(data);
})
.catch(error => {
// 处理错误
console.error('There was a problem with the fetch operation:', error);
});
自定义请求头
Fetch API 允许你自定义请求头,以便在请求中包含所需的信息。你可以通过传递一个对象作为第二个参数来设置请求的配置,其中包括 headers 属性来定义请求头。
const headers = new Headers();
headers.append('Content-Type', 'application/json');
fetch('https://api.example.com/data', {
method: 'POST',
headers: headers,
body: JSON.stringify({ username: 'example', password: '123456' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
//我们创建了一个包含自定义请求头的 Headers 对象,并在请求中传递了这个对象,以便服务器能够正确解析请求。
操作标头
Response 对象还有一个Response.headers属性,指向一个 Headers 对象,对应 HTTP 回应的所有标头。
const response = await fetch(url);
for (let [key, value] of response.headers) {
console.log(`${key} : ${value}`);
}
response.headers.get():根据指定的键名,返回键值。
response.headers.has(): 返回一个布尔值,表示是否包含某个标头。
response.headers.set():将指定的键名设置为新的键值,如果该键名不存在则会添加。
response.headers.append():添加标头。
response.headers.delete():删除标头。
response.headers.keys():返回一个遍历器,可以依次遍历所有键名。
response.headers.values():返回一个遍历器,可以依次遍历所有键值。
response.headers.entries():返回一个遍历器,可以依次遍历所有键值对([key, value])。
response.headers.forEach():依次遍历标头,每个标头都会执行一次参数函数。
FormData 请求数据
Fetch API 支持使用 FormData 对象来处理表单数据。你可以将 FormData 对象传递给 fetch() 函数的 body 参数,从而方便地发送表单数据。
const formData = new FormData();
formData.append('username', 'example');
formData.append('password', '123456');
fetch('https://api.example.com/login', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
//我们创建了一个 FormData 对象,并向其添加了表单字段。然后将该对象作为请求的 body 参数传递给 fetch() 函数。
中断请求
使用 AbortController 和 AbortSignal,可以在需要时中断 Fetch 请求。这对于需要取消或中止某些操作的情况非常有用。
const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 5000); // 5秒后中断请求
fetch('https://api.example.com/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
//我们创建了一个 AbortController,并在 5 秒后调用了 abort() 方法来中断请求。
缓存
Fetch API 支持使用缓存来提高性能。你可以通过设置请求的 cache 属性来控制缓存策略。参数:default,force-cache,no-cache,no-store,only-if-cached,reload
fetch('https://api.example.com/data', {
method: 'GET',
cache: 'no-store' // 禁用缓存 或 'reload' 以强制重新加载资源
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
//我们通过设置 cache 属性为 'no-store' 来禁用缓存。
读取内容
Response对象根据服务器返回的不同类型的数据,提供了不同的读取方法。
const response = await fetch(url);
response.text():得到文本字符串,用于获取文本数据,比如 HTML 文件。
response.json():得到 JSON 对象。
response.blob():得到二进制 Blob 对象,例如读取图片文件,显示在网页上。
response.formData():得到 FormData 表单对象,主要用在 Service Worker 里面,拦截用户提交的表单,修改某些数据以后,再提交给服务器。
response.arrayBuffer():得到二进制 ArrayBuffer 对象,主要用于获取流媒体文件。
fetch封装
function request(url, options = {}) {
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
body: null,
};
const requestOptions = { ...defaultOptions, ...options };
return fetch(url, requestOptions)
.then(response => {
const contentType = response.headers.get('content-type');
if (!response.ok) {
throw new Error(`请求失败: ${response.status}`);
} else if (contentType && contentType.includes('application/json')) {
return response.json();
} else {
return response.text();
}
})
.catch(error => {
console.error('请求失败:', error);
throw error;
});
}
// 使用示例
const apiUrl = 'https://jsonplaceholder.typicode.com/posts';
// 发起GET请求
request(apiUrl)
.then(data => {
console.log('GET请求成功:', data);
})
.catch(error => {
console.error('GET请求失败:', error);
});
// 发起POST请求
const postData = {
title: 'foo',
body: 'bar',
userId: 1,
};
const postOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
};
request(apiUrl, postOptions)
.then(data => {
console.log('POST请求成功:', data);
})
.catch(error => {
console.error('POST请求失败:', error);
});//将默认的请求选项定义为一个对象,并且在用户提供的选项和默认选项之间进行合并。//根据响应的内容类型来决定是解析为JSON格式还是纯文本格式。