Fetch API 与 XMLHttpRequest
Fetch API vs XMLHttpRequest
我知道 Fetch API 使用 Promise
s 并且它们都允许您向服务器发出 AJAX 请求。
我读到 Fetch API 有一些额外的功能,这些功能在 XMLHttpRequest
中不可用(在 Fetch API polyfill 中,因为它基于 XHR
).
Fetch API 有哪些额外的功能?
有些事情您可以使用 fetch 而不是 XHR:
- 您可以将缓存 API 与请求和响应对象一起使用;
- 您可以执行
no-cors
请求,从未实现 CORS 的服务器获取响应。您不能直接从 JavaScript 访问响应主体,但可以将其与其他 API 一起使用(例如缓存 API);
- 流式响应(使用 XHR,整个响应缓冲在内存中,使用 fetch,您将能够访问低级流)。这在所有浏览器中尚不可用,但很快就会可用。
有一些事情可以用 XHR 做,而用 fetch 还不能做,但它们迟早会可用(阅读此处的 "Future improvements" 段落:https://hacks.mozilla.org/2015/03/this-api-is-so-fetching/):
- 中止请求(这现在在 Firefox 和 Edge 中有效,正如@sideshowbarker 在他的评论中解释的那样);
- 报告进度。
获取
- 缺少使用文档的内置方法
- 无法设置超时yet
- 无法覆盖 content-type 响应 header
- 如果 content-length 响应 header 存在 但未公开 ,body 的总长度在流式传输期间未知
- 如果请求已经完成,将调用信号的中止处理程序甚至
- 无上传进度(支持
ReadableStream
个实例作为请求主体 yet to come)
- doesn't support
--allow-file-access-from-files
(铬)
XHR
- 没有办法 不 发送 cookie(除了使用 non-standard
mozAnon
flag 或 AnonXMLHttpRequest
构造函数)
- 不能 return
FormData
个实例
- 没有等同于
fetch
的 no-cors
模式
- 始终遵循重定向
上面的答案很好,提供了很好的见解,但我和这篇 google developers blog entry 的观点相同,主要区别(从实际角度来看)是 built-in 从 fetch
返回的承诺
不必像这样编写代码
function reqListener() {
var data = JSON.parse(this.responseText);
}
function reqError(err) { ... }
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
我们可以清理一些东西,用 promises 和现代语法写一些更简洁、更易读的东西
fetch('./api/some.json')
.then((response) => {
response.json().then((data) => {
...
});
})
.catch((err) => { ... });
我知道 Fetch API 使用 Promise
s 并且它们都允许您向服务器发出 AJAX 请求。
我读到 Fetch API 有一些额外的功能,这些功能在 XMLHttpRequest
中不可用(在 Fetch API polyfill 中,因为它基于 XHR
).
Fetch API 有哪些额外的功能?
有些事情您可以使用 fetch 而不是 XHR:
- 您可以将缓存 API 与请求和响应对象一起使用;
- 您可以执行
no-cors
请求,从未实现 CORS 的服务器获取响应。您不能直接从 JavaScript 访问响应主体,但可以将其与其他 API 一起使用(例如缓存 API); - 流式响应(使用 XHR,整个响应缓冲在内存中,使用 fetch,您将能够访问低级流)。这在所有浏览器中尚不可用,但很快就会可用。
有一些事情可以用 XHR 做,而用 fetch 还不能做,但它们迟早会可用(阅读此处的 "Future improvements" 段落:https://hacks.mozilla.org/2015/03/this-api-is-so-fetching/):
- 中止请求(这现在在 Firefox 和 Edge 中有效,正如@sideshowbarker 在他的评论中解释的那样);
- 报告进度。
获取
- 缺少使用文档的内置方法
- 无法设置超时yet
- 无法覆盖 content-type 响应 header
- 如果 content-length 响应 header 存在 但未公开 ,body 的总长度在流式传输期间未知
- 如果请求已经完成,将调用信号的中止处理程序甚至
- 无上传进度(支持
ReadableStream
个实例作为请求主体 yet to come) - doesn't support
--allow-file-access-from-files
(铬)
XHR
- 没有办法 不 发送 cookie(除了使用 non-standard
mozAnon
flag 或AnonXMLHttpRequest
构造函数) - 不能 return
FormData
个实例 - 没有等同于
fetch
的no-cors
模式 - 始终遵循重定向
上面的答案很好,提供了很好的见解,但我和这篇 google developers blog entry 的观点相同,主要区别(从实际角度来看)是 built-in 从 fetch
不必像这样编写代码
function reqListener() {
var data = JSON.parse(this.responseText);
}
function reqError(err) { ... }
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
我们可以清理一些东西,用 promises 和现代语法写一些更简洁、更易读的东西
fetch('./api/some.json')
.then((response) => {
response.json().then((data) => {
...
});
})
.catch((err) => { ... });