一、引言
在前端开发中,网络请求是必不可少的一部分。从早期的 XMLHttpRequest 到如今的 Fetch API,网络请求的方式在不断演进。Fetch API 作为现代的网络请求方案,以其简洁的 API 设计和基于 Promise 的异步处理方式,受到了广大开发者的喜爱。

二、Fetch API 概述
2.1 什么是 Fetch API
Fetch API 是一种新的网络请求接口,它提供了一种更现代化、更简洁的方式来发起网络请求。它基于 Promise,这意味着我们可以使用 async/await 或者 .then() 方法来处理请求的结果,避免了传统回调函数带来的嵌套问题。
2.2 与 XMLHttpRequest 的对比
| 特性 | XMLHttpRequest | Fetch API |
|---|---|---|
| API 复杂度 | 较高,需要手动管理多个状态和事件 | 简洁,基于 Promise,易于使用 |
| 异步处理 | 基于回调函数,容易出现回调地狱 | 基于 Promise,支持 async/await |
| 响应处理 | 需要手动解析响应数据 | 提供了方便的方法来处理不同类型的响应数据 |
三、Fetch API 的基本使用
3.1 发起简单的 GET 请求
javascript
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
上述代码中,我们使用 fetch() 函数发起了一个 GET 请求。fetch() 函数返回一个 Promise,当请求成功时,我们通过 response.ok 来检查响应状态是否正常。如果正常,我们使用 response.json() 方法将响应数据解析为 JSON 格式。
3.2 发起 POST 请求
javascript
const data = {
name: 'John Doe',
age: 30
};
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
在这个例子中,我们发起了一个 POST 请求。通过第二个参数传递一个配置对象,我们可以指定请求的方法、请求头和请求体。请求体需要使用 JSON.stringify() 方法将 JavaScript 对象转换为 JSON 字符串。
四、Fetch API 的配置选项
4.1 method
method 用于指定请求的方法,常见的有 GET、POST、PUT、DELETE 等。
javascript
fetch('https://api.example.com/data', {
method: 'DELETE'
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.text();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
4.2 headers
headers 用于设置请求头。例如,我们可以设置 Content-Type 来指定请求体的格式。
javascript
fetch('https://api.example.com/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'name=John&age=30'
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
4.3 body
body 用于设置请求体。请求体的格式需要根据 Content-Type 来确定。
javascript
const formData = new FormData();
formData.append('name', 'John Doe');
formData.append('age', 30);
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
4.4 mode
mode 用于指定请求的模式,常见的有 cors、no-cors、same-origin 等。
javascript
fetch('https://api.example.com/data', {
mode: 'cors'
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
五、处理响应数据
5.1 解析不同类型的响应数据
- JSON 数据 :使用
response.json()方法。
javascript
fetch('https://api.example.com/json-data')
.then(response => response.json())
.then(data => {
console.log(data);
});
- 文本数据 :使用
response.text()方法。
javascript
fetch('https://api.example.com/text-data')
.then(response => response.text())
.then(text => {
console.log(text);
});
- 二进制数据 :使用
response.blob()方法。
javascript
fetch('https://api.example.com/image')
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);
});
5.2 处理响应状态码
我们可以通过 response.status 和 response.statusText 来获取响应的状态码和状态文本。
javascript
fetch('https://api.example.com/data')
.then(response => {
console.log('Status code:', response.status);
console.log('Status text:', response.statusText);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
六、错误处理
6.1 网络错误
当网络出现问题时,fetch() 函数返回的 Promise 会被 reject。
javascript
fetch('https://nonexistent-api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
6.2 响应错误
即使请求成功,服务器也可能返回错误的响应。我们可以通过 response.ok 来检查响应状态。
javascript
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
七、兼容性和替代方案
7.1 兼容性
Fetch API 在现代浏览器中得到了广泛支持,但在一些旧版本的浏览器中可能不支持。我们可以使用 Polyfill 来解决兼容性问题。
7.2 替代方案
如果 Fetch API 不适用,我们可以使用 XMLHttpRequest 或者 Axios 等库来发起网络请求。
八、总结
Fetch API 作为现代的网络请求方案,提供了简洁的 API 和基于 Promise 的异步处理方式,使得网络请求变得更加简单和高效。通过本文的介绍,我们了解了 Fetch API 的基本使用、配置选项、响应数据处理、错误处理等方面的知识。在实际开发中,我们可以根据具体需求选择合适的网络请求方式。