Appearance
Fetch API
基本请求操作
初始化请求
fetch(url, options)- 返回一个 Promise,表示请求的响应
- 所有 fetch 请求都是异步的,通过 Promise 处理
基础配置
超时控制
- fetch 本身不直接支持超时,需要结合 AbortController 和 setTimeout 实现
jsconst controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒超时 fetch(url, { signal: controller.signal }) .then(response => /* 处理响应 */) .catch(err => { if (err.name === 'AbortError') console.log('请求超时'); }) .finally(() => clearTimeout(timeoutId));设置请求头
jsfetch(url, { headers: { "Content-Type": "application/json", "Custom-Header": "value", }, });- 也可使用 Headers 类:
new Headers({'Content-Type': 'application/json'})
- 也可使用 Headers 类:
响应数据类型
- 不需要预设,而是通过响应对象的方法来处理不同类型
response.text()- 返回文本字符串的 Promiseresponse.json()- 返回解析为 JSON 的 Promiseresponse.blob()- 返回 Blob 对象的 Promiseresponse.arrayBuffer()- 返回 ArrayBuffer 的 Promiseresponse.formData()- 返回 FormData 的 Promise
- 不需要预设,而是通过响应对象的方法来处理不同类型
请求发送
通过 options 对象的 body 参数设置请求体
jsfetch(url, { method: "POST", body: JSON.stringify(data), // 字符串 // body: new FormData(form) // FormData // body: new Blob([...]) // Blob // body: new URLSearchParams('key=value') // URLSearchParams });- 注意:GET 或 HEAD 请求不能包含 body
取消请求
使用 AbortController 取消请求
jsconst controller = new AbortController(); const signal = controller.signal; fetch(url, { signal }) .then(response => /* 处理响应 */) .catch(err => { if (err.name === 'AbortError') console.log('请求被取消'); }); // 在需要时取消请求 controller.abort();
响应消费
检查响应状态
jsfetch(url).then((response) => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } return response.json(); });读取响应数据
- 注意:响应体只能被消费一次
错误处理
fetch 只有在网络错误或请求被阻止时才会 reject
HTTP 错误状态(如 404 或 500)不会导致 Promise 被拒绝
jsfetch(url) .then((response) => { if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); return response.json(); }) .then((data) => console.log(data)) .catch((error) => console.error("Fetch error:", error));
CORS
鉴权信息
credentials控制是否发送 cookiesjsfetch(url, { credentials: "same-origin", // 默认值,只在同源请求中发送 cookies // credentials: 'include' // 在所有请求中发送 cookies(跨域也发送) // credentials: 'omit' // 不发送 cookies });- 跨域请求需要服务器设置
Access-Control-Allow-Credentials: true - 跨域请求需要服务器设置特定的
Access-Control-Allow-Origin,不能使用通配符 *
- 跨域请求需要服务器设置
进度监控
下载进度
jsfetch(url).then((response) => { const reader = response.body.getReader(); const contentLength = +response.headers.get("Content-Length"); let receivedLength = 0; let chunks = []; return new Promise((resolve, reject) => { function processChunk({ done, value }) { if (done) { const body = new Uint8Array(receivedLength); let position = 0; for (let chunk of chunks) { body.set(chunk, position); position += chunk.length; } resolve(body); return; } receivedLength += value.length; chunks.push(value); console.log( `已接收 ${receivedLength} of ${contentLength} (${Math.round( (receivedLength / contentLength) * 100 )}%)` ); return reader.read().then(processChunk); } reader.read().then(processChunk); }); });上传进度
- fetch API 本身不直接支持上传进度
- 可以使用较新的 Streams API 实现
- 注意由于 Stream 在 chrome 使用 http2 上传,会导致丢失 content-length 头部, 可以利用自定义头部解决此问题
特有功能
请求模式
jsfetch(url, { mode: "cors", // 默认值,允许跨域请求 // mode: 'no-cors', // 限制跨域请求 // mode: 'same-origin', // 只允许同源请求 // mode: 'navigate' // 用于浏览器导航 });缓存控制
jsfetch(url, { cache: "default", // 默认,使用浏览器的标准缓存规则 // cache: 'no-store', // 不使用缓存 // cache: 'reload', // 忽略缓存,重新获取资源 // cache: 'no-cache', // 验证缓存是否过期 // cache: 'force-cache', // 即使过期也使用缓存 // cache: 'only-if-cached' // 只使用缓存,不访问网络 });重定向处理
jsfetch(url, { redirect: "follow", // 默认,自动跟随重定向 // redirect: 'error', // 重定向时抛出错误 // redirect: 'manual' // 手动处理重定向 });