获取 API 与 XMLHttpRequest

IT技术 javascript ajax xmlhttprequest fetch-api
2021-02-16 22:15:59

我知道 Fetch API 使用Promises 并且它们都允许您向服务器发出 AJAX 请求。

我已经读到 Fetch API 有一些额外的功能,这些功能在XMLHttpRequest(和 Fetch API polyfill中不可用,因为它基于XHR)。

Fetch API 有哪些额外的功能?

3个回答

你可以用 fetch 而不是 XHR 做一些事情:

  • 您可以将缓存 API 与请求和响应对象一起使用;
  • 您可以执行no-cors请求,从未实现 CORS 的服务器获取响应。您不能直接从 JavaScript 访问响应正文,但您可以将其与其他 API(例如缓存 API)一起使用;
  • 流响应(使用 XHR,整个响应缓冲在内存中,使用 fetch 您将能够访问低级流)。这并非在所有浏览器中都可用,但很快就会出现。

您可以使用 XHR 完成一些使用 fetch 无法完成的事情,但它们迟早会可用(阅读此处的“未来改进”段落:https://hacks.mozilla .org/2015/03/this-api-is-so-fetching/):

  • 中止请求(这现在适用于 Firefox 和 Edge,正如@sideshowbarker 在他的评论中所解释的那样);
  • 报告进展。

这篇文章https://jakearchibald.com/2015/thats-so-fetch/包含更详细的描述。

2021 年的报告,仍然无法跟踪使用fetchAPI创建的请求(或响应)的进度XMLHttpRequest因此,如果有的话,他会慢慢地痛苦地死去。
2021-04-17 22:15:59
而且,根据我的经验,fetch可以请求文件,但 XHR 不能。
2021-04-30 22:15:59
Fetch API 的规范现在提供取消。到目前为止,Firefox 57 和 Edge 16 已提供支持。 演示:fetch-abort-demo-edge.glitch.memdn.github.io/dom-examples/abort-api并且有开放的 Chrome 和 Webkit 功能错误bugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980操作方法:developers.google.com/web/updates/2017/09/abortable-fetchdeveloper.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples以及stackoverflow.com/a/47250621/441757 上的 Stack Overflow 答案中的示例
2021-05-10 22:15:59
另一个区别是fetch无法在开发人员工具上重放请求。
2021-05-12 22:15:59

拿来

  • 缺少使用文档的内置方法
  • 没有办法设置超时
  • 无法覆盖内容类型响应标头
  • 如果 content-length 响应头存在但未公开,则在流传输期间主体的总长度未知
  • 即使请求已完成,也会调用信号的中止处理程序
  • 没有上传进度(对ReadableStream请求主体的支持尚未到来

XHR

  • 没有办法发送 cookie(除了使用非标准mozAnon标志AnonXMLHttpRequest构造函数)
  • 无法返回FormData实例
  • 没有等效于fetchno-cors模式
  • 始终遵循重定向
“无法覆盖响应的内容类型标头”......这只是一个坏主意。'content-type 指示要返回的内容,而后端应将其指示给前端。事实上,内容类型应该是类型的“唯一标题”,因为所请求的就是应该返回的。如果您想要从特殊子域或其他地方提供不同的服务,以便您可以单独处理特定功能。你试图将 1% 的规则强加于每个人 99% 的喉咙。
2021-04-16 22:15:59
2021-04-29 22:15:59
@rzr 不完全是,你得到了Response#body.
2021-05-07 22:15:59
fetch也缺少进展。使用 XHR,您可以跟踪progress事件的进度
2021-05-10 22:15:59
@Knu 是的,现在我们更先进了,我们可以轻松地自动化 90% 的解决方案,让异常情况路由到不同的功能。
2021-05-14 22:15:59

上面的答案很好,提供了很好的见解,但我与谷歌开发者博客文章中的观点相同,主要区别(从实际角度来看)是从返回的内置Promise的便利性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();

我们可以用promise和现代语法清理一些东西并写一些更简洁易读的东西

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
我讨厌 IE,但我也不建议放弃 IE 支持,尤其是当有 polyfill 时。数百万人仍在使用 IE 和其他旧浏览器。就在几天前,我不得不告诉客户在我看到他使用 IE 后不要使用它。当然,如果您的项目无论如何都不会支持 IE,那么 polyfill 将无济于事。
2021-04-25 22:15:59
我认为这是微软的纯粹营销。如果他们将 IE 留在安装了 Edge 的计算机上,那么他们希望人们会认为 Edge 是一个不同的浏览器(不是),IE 的坏名声将随着 IE 消失。唯一的区别是 Edge 比 IE 更新。但是,如果您不确定自己拥有最新版本的 Edge,那么您不妨使用 IE。
2021-04-25 22:15:59
@PHPGuru grr!这让我很生气。所有最新的网络技术在 Internet Explorer 上都完全不可用。我希望人们至少会切换到 Microsoft Edge!我希望 MS 向 IE 发出“更新”,这将完全禁用浏览器(或在允许使用之前显示一个唠叨的屏幕)并告诉人们切换到另一个浏览器。
2021-05-05 22:15:59
@TheOpti 您可以在 IE 11 中填充基本的 fetch 支持。您也可以在许多项目中将 IE11 作为受支持的浏览器删除,因为在许多用户群中 IE 11 的使用率现在低于 1%。
2021-05-11 22:15:59