WHATWG Fetch 是一个现代 JavaScript API,用于进行 HTTP 请求和处理响应。它是 Fetch 标准的一部分,由万维网超级工作组(WHATWG)开发,用来替代早期的 XMLHttpRequest 对象,提供更简洁和强大的接口。
Fetch API 的核心是一个简单的全局 fetch
函数,它返回一个 Promise
,该 Promise 解析为代表请求结果的 Response
对象。基本的用法如下:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('There has been a problem with your fetch operation:', error));
在这个例子中,fetch 函数首先发起一个 HTTP GET 请求。当请求完成时,返回的 Response
对象的 ok
属性用于判断请求是否成功。通过 response.json()
方法将响应内容解析为 JSON 格式。在任何一个步骤发生错误时,可以通过 catch 方法来进行错误处理。
指定请求方法和头部
Fetch API 的第二个参数是一个可选的配置对象,可以通过它设置请求方法、请求头等。以下是一个 POST 请求的示例:
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
在这个例子中,方法被设置为 POST,并且请求头中设置了 Content-Type
为 application/json
表示发送 JSON 格式数据。
处理不同类型的响应
除了 .json()
,Response
对象还提供了其他方法来解析响应体:
.text()
- 将响应解析为字符串。.blob()
- 将响应解析为二进制的大对象(Blob)。.arrayBuffer()
- 将响应解析为 ArrayBuffer,用于处理底层二进制数据。.formData()
- 将响应解析为 FormData 对象,适合处理 multipart/form-data
类型数据。示例代码:
fetch('https://api.example.com/image')
.then(response => response.blob())
.then(imageBlob => {
const imageURL = URL.createObjectURL(imageBlob);
document.querySelector('img').src = imageURL;
})
.catch(error => console.error('Error:', error));
Fetch 本身不支持请求取消,可以结合 AbortController
使用。AbortController 提供了一种方法来中止 fetch 请求:
const controller = new AbortController();
const signal = controller.signal;
fetch('https://api.example.com/slow-endpoint', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => {
if (error.name === 'AbortError') {
console.error('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
});
// 在某个条件下中止请求
controller.abort();
在这个例子中,通过创建 AbortController
,将其 signal
属性传递给 fetch 请求,然后可以调用 controller.abort()
方法来中止该请求。
Fetch 请求默认符合 CORS(Cross-Origin Resource Sharing)策略。对于跨域请求,服务器需要正确设置响应头,例如 Access-Control-Allow-Origin
,以允许来自不同源的请求。
fetch('https://api.different-origin.com/data')
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
})
.then(data => console.log(data))
.catch(error => console.error('There has been a problem with your fetch operation:', error));
如果服务器不配置 CORS 标头,浏览器的请求将被阻止。对于复杂请求,例如使用非标准 HTTP 方法或自定义头部的请求,服务器可能需要附加的预检请求。
尽管 Fetch API 是现代浏览器的一个内置特性,但在复杂的应用中,一些开发者可能更倾向于使用更高级的库,如 Axios。以下是一些对比:
Fetch 的优势
XMLHttpRequest
易于使用。Axios 的优势
WHATWG Fetch 提供了一种现代化的方式来进行 HTTP 请求,它利用 Promise 使异步操作更加简洁和清晰。通过支持流、请求取消、跨域请求等,Fetch 几乎可以满足大多数常见的 web 开发需求。然而,在某些复杂场景下,可能仍然需要借助像 Axios 这样的第三方库。无论选择何种方式,开发者都应针对应用场景选择合适的工具,以提高开发效率和代码可读性。