fetch 是什么
fetch是一个现代的,用于网络请求的 js api
基于 Promise:fetch 的所有操作都返回一个 promise 对象,这使得我们可以用 .then(), .catch() (注册promise成功和失败时要执行的回调函数)以及 async/await 这种更现代、更优雅的方式来处理异步操作,避免了“回调地狱”(Callback Hell)
fetch 操作本身是
同步的,但是它会返回一个promise,所以可以使用.then和.catch来注册成功和失败时的回调函数. .then .catch 都是微任务触发时会推入微任务队列。
第二部分:Fetch 的用法
fetch 的基本语法是 fetch(url, options)。
- url:你想要请求的地址。(默认是
get请求) - options (可选):一个配置对象,用于自定义请求,如
请求方法、请求头、请求体等。
1. 基本的 GET 请求
这是最简单的用法,options 参数可以省略,默认就是 GET 请求。
fetch('https://api.github.com/users/github')
.then(response => {
// 检查响应状态是否成功 (status code 200-299)
if (!response.ok) {
throw new Error('Network response was not ok: ' + response.statusText);
}
// 将响应体解析为 JSON
return response.json();
})
.then(data => {
// 在这里处理最终的数据
console.log(data);
})
.catch(error => {
// 在这里处理网络错误或上面抛出的错误
console.error('Fetch error:', error);
});
关键点解释:
- 第一次 .then(response => ...) :fetch 返回的 Promise 在收到服务器的响应头后就会立即兑现(resolve),而不是等整个响应体下载完成。这个 response 对象是一个 Response 对象,它包含了响应的状态码、头部信息等,但不直接包含数据。
response.json():这是一个方法,用于读取 Response 对象中的响应体(body),并将其解析为JSON。这个方法本身也返回一个 Promise。其他类似的方法还有 response.text() (解析为文本), response.blob() (解析为二进制对象) 等。
- 第二次 .then(data => ...) :这个 .then 处理的是 response.json() 返回的 Promise,此时 data 才是我们需要的最终 JSON 数据。
- .catch(error => ...) :用于捕获**
网络层面的错误**(比如DNS解析失败、用户离线)或者我们在代码中手动 throw 的错误。
2. 发起 POST 请求
当需要发送数据给服务器时(如创建新用户、提交表单),你需要使用 POST 请求,并在 options 对象中配置 method, headers, 和 body。
const userData = {
name: 'John Doe',
job: 'Developer'
};
fetch('https://reqres.in/api/users', {
method: 'POST', // 指定请求方法
headers: {
'Content-Type': 'application/json' // 告诉服务器我们发送的是 JSON 格式的数据
},
body: JSON.stringify(userData) // 将 JavaScript 对象转换为 JSON 字符串
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});
3. 错误处理(非常重要!) fetch 返回的promise对象只有在 网络失败时 才会成为失败(reject)的状态
fetch 的一个重要特性是:只要服务器有响应,即使响应是 HTTP 错误状态码(如 404 Not Found, 500 Internal Server Error),fetch 返回的 Promise 也不会被拒绝(reject) 。它只会在网络失败(例如,无法连接到服务器)时才会拒绝。
因此,你必须手动检查响应状态,如下所示:
codeJavaScript
fetch('https://httpstat.us/404') // 这个地址会返回一个 404 错误
.then(response => {
console.log('Response received, status:', response.status); // 会打印 404
if (!response.ok) { // response.ok 对于 200-299 的状态码为 true
// 如果状态码不是 2xx,我们手动抛出一个错误
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
// .catch() 会捕获到我们上面手动抛出的错误
console.error('There was a problem with the fetch operation:', error);
});
4. 使用 async/await 语法
async/await 是处理 Promise 的语法糖,能让异步代码看起来像同步代码,更加清晰。
codeJavaScript
async function postData(url = '', data = {}) {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json(); // 等待 JSON 解析完成
console.log('Success:', result);
return result;
} catch (error) {
console.error('Error:', error);
}
}
postData('https://reqres.in/api/users', { name: 'Jane Doe', job: 'Designer' });
fetch 的 response
🧩 一、Response 是什么?
在浏览器中,fetch() resolve一个 Response 对象,
它是对 HTTP 响应的封装,属于 Fetch API。
它包含:
- 响应头(headers)
- 响应体(body)
- 状态信息(status、ok、type...)
- 一些工具方法(如
.json()、.text())
你可以理解为:
Response 就是一个「HTTP 响应报文」在 JS 里的对象化表示。
🧱 二、Response 对象的所有属性总览
| 属性名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
type | string | 响应类型(跨域相关) | "basic", "cors", "opaque", "error", "default" |
url | string | 实际响应的 URL(可能重定向后) | "https://example.com/data.json" |
redirected | boolean | 是否经过重定向 | false |
status | number | HTTP 状态码 | 200 |
statusText | string | HTTP 状态文本 | "OK" |
ok | boolean | 状态码是否在 200–299 范围内 | true |
headers | Headers | 响应头对象 | Headers { content-type: "application/json" } |
body | ReadableStream | 响应体的流(原始字节数据) | ReadableStream { ... } |
bodyUsed | boolean | body 是否已被读取 | false(读取一次后变 true) |