fetch
是现代 JavaScript 中用于发起网络请求的一个全局 API。它提供了一种简单、灵活的方式来与服务器进行通信,基于 Promise
,因此非常适合处理异步操作。fetch
是 XMLHttpRequest
的替代品,广泛用于前端开发中。
基础
基本用法
fetch
的基本语法如下:
|
|
resource
: 请求的资源,通常是一个 URL。options
: 可选的配置对象,用于指定请求的方法、头信息、请求体等。
示例:GET 请求
|
|
示例:POST 请求
|
|
处理响应
fetch
返回的 response
对象包含多种方法来处理不同类型的响应数据:
response.json()
: 将响应体解析为 JSON 格式。response.text()
: 将响应体解析为文本格式。response.blob()
: 将响应体解析为Blob
对象。response.arrayBuffer()
: 将响应体解析为ArrayBuffer
对象。
|
|
处理错误
fetch
只有在网络错误(如无法连接到服务器)时才会进入 catch
块。如果服务器返回一个错误状态码(如 404 或 500),fetch
不会自动抛出错误,你需要手动检查 response.ok
或 response.status
。
|
|
使用 async/await
fetch
与 async/await
结合使用可以使代码更加简洁和易读。
|
|
配置选项
fetch
的 options
参数可以包含以下常用选项:
method
: 请求方法(如GET
,POST
,PUT
,DELETE
)。headers
: 请求头(如Content-Type
,Authorization
)。body
: 请求体(通常用于POST
或PUT
请求)。mode
: 请求模式(如cors
,no-cors
,same-origin
)。credentials
: 是否发送 cookies(如omit
,same-origin
,include
)。cache
: 缓存模式(如default
,no-store
,reload
,no-cache
,force-cache
)。redirect
: 重定向模式(如follow
,error
,manual
)。
|
|
总结
fetch
是一个强大且灵活的 API,用于发起网络请求。它基于 Promise
,因此非常适合处理异步操作。通过 fetch
,你可以轻松地与服务器进行通信,处理各种类型的响应数据,并结合 async/await
使代码更加简洁和易读。
附录
fetch 相较于传统的 XHR 的优势和不足
优势的方面
1、基于 Promise
- 优势:
fetch
基于Promise
,使得异步代码的编写更加简洁和直观。可以使用then()
和catch()
链式调用,或者结合async/await
编写更易读的代码。1 2 3 4
fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));
- 对比 XHR: XHR 使用回调函数处理异步操作,容易导致“回调地狱”,代码可读性较差。
2、更简洁的 API
- 优势:
fetch
的 API 设计更加简洁,语法更现代化。只需调用fetch(url, options)
,而不需要像 XHR 那样手动设置open()
、send()
和事件监听器。1 2 3 4 5
fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'value' }) });
- 对比 XHR: XHR 的 API 较为冗长,需要手动设置请求方法、头信息和事件监听器。
3、内置支持多种数据格式
- 优势:
fetch
提供了内置方法来处理不同类型的响应数据(如response.json()
、response.text()
、response.blob()
等),使得处理响应更加方便。1 2 3
fetch('https://api.example.com/data') .then(response => response.json()) // 自动解析 JSON .then(data => console.log(data));
- 对比 XHR: XHR 需要手动解析响应数据(如
JSON.parse(xhr.responseText)
)。
4、更现代的错误处理
- 优势:
fetch
的错误处理更加现代化。只有网络错误(如无法连接到服务器)才会触发catch
块,而 HTTP 错误(如 404 或 500)不会自动抛出错误,需要手动检查response.ok
或response.status
。1 2 3 4 5 6 7 8
fetch('https://api.example.com/data') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .catch(error => console.error(error));
- 对比 XHR: XHR 的错误处理依赖于
status
属性,需要手动检查状态码。
5、支持跨域请求(CORS)
- 优势:
fetch
默认支持跨域请求(CORS),并且可以通过mode
选项(如cors
、no-cors
、same-origin
)灵活控制请求的行为。1 2 3
fetch('https://api.example.com/data', { mode: 'cors' });
- 对比 XHR: XHR 也支持 CORS,但配置相对复杂。
6、支持流式数据
- 优势:
fetch
支持流式数据处理,可以逐步读取大文件或流式响应。1 2 3 4 5
fetch('https://api.example.com/large-file') .then(response => response.body.getReader()) .then(reader => { // 逐步读取数据 });
- 对比 XHR: XHR 不支持流式数据处理。
不足的方面
1、不支持进度事件
- 不足:
fetch
不支持进度事件(如xhr.upload.onprogress
或xhr.onprogress
),因此无法实时监控文件上传或下载的进度。1 2 3 4
const xhr = new XMLHttpRequest(); xhr.upload.onprogress = function (event) { console.log(`Uploaded ${event.loaded} of ${event.total} bytes`); };
- 对比 XHR: XHR 提供了
onprogress
事件,可以方便地监控上传或下载的进度。
2、默认不发送 cookies
- 不足:
fetch
默认不会发送跨域请求的 cookies(除非显式设置credentials: 'include'
)。1 2 3
fetch(' https://api.example.com/data ', { credentials: 'include' // 需要显式开启 });
- 对比 XHR: XHR 默认会发送 cookies,无需额外配置。
3、不支持超时设置
- 不足:
fetch
没有内置的超时机制,需要手动实现超时逻辑。1 2 3 4 5 6 7
const controller = new AbortController(); const signal = controller.signal; setTimeout(() => controller.abort(), 5000); // 5 秒超时 fetch(' https://api.example.com/data ', { signal }) .catch(error => console.error('Request timed out'));
- 对比 XHR: XHR 提供了
timeout
属性,可以轻松设置请求超时。
4、兼容性问题
- 不足:
fetch
在某些旧版浏览器(如 IE11)中不被支持,需要使用 polyfill 来兼容。1 2
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.6.2/dist/fetch.umd.min.js"></script>
- 对比 XHR: XHR 在所有现代浏览器和旧版浏览器中都得到了广泛支持。
5、复杂场景下功能不足
- 不足: 在某些复杂场景下(如需要精细控制请求行为或处理二进制数据),
fetch
的功能可能不如 XHR 灵活。 - 对比 XHR: XHR 提供了更底层、更精细的控制能力。
总结
特性 | fetch 优势 |
fetch 不足 |
---|---|---|
API 设计 | 基于 Promise ,语法简洁,支持链式调用和 async/await 。 |
不支持进度事件,无法实时监控上传或下载进度。 |
错误处理 | 现代化错误处理,结合 Promise 更易读。 |
默认不发送 cookies,需要显式配置。 |
数据处理 | 内置支持多种数据格式(如 JSON、文本、Blob)。 | 不支持超时设置,需要手动实现。 |
兼容性 | 现代浏览器支持良好,但需要 polyfill 兼容旧版浏览器。 | 在旧版浏览器(如 IE11)中不被支持。 |
功能灵活性 | 支持流式数据处理,适合处理大文件或流式响应。 | 在复杂场景下功能不如 XHR 灵活。 |
通过以上对比可以看出,fetch
是一个更现代化、更简洁的 API,适合大多数场景。但在需要精细控制请求行为或兼容旧版浏览器的场景下,XHR 仍然是一个可靠的选择。