Fetch API和XMLHttpRequest有什么区别?

ily*_*iuk 141 javascript ajax xmlhttprequest fetch-api

我知道fetch正在使用promises,它们都允许你向服务器发出AJAX请求.我已经读过fetch有一些额外的功能,这些功能在XMLHttpRequest(以及fetch polyfill中,因为它基于XHR)中不可用.fetch API有哪些额外功能?

Mar*_*rco 101

使用fetch可以执行一些操作,而不是使用XHR:

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

您可以使用XHR执行一些使用fetch无法完成的操作,但它们迟早会可用(请阅读"未来改进"段落:https://hacks.mozilla .org/2015/03/this-api-is-so-fetching /):

  • 中止请求(现在可以在Firefox和Edge中使用,正如@sideshowbarker在他的评论中解释的那样);
  • 报告进度.

本文https://jakearchibald.com/2015/thats-so-fetch/包含更详细的说明.

  • 另一个区别是“fetch”请求无法在开发人员工具上重放。 (6认同)
  • 到 2021 年报告,仍然无法跟踪使用“fetch” API 创建的请求(或响应)的进度。因此,“XMLHttpRequest”会慢慢地痛苦地死去(如果有的话)。 (4认同)
  • 而且,根据我的经验,“fetch”可以请求文件,但 XHR 不能。 (3认同)
  • Fetch API 的规范现在提供了取消功能。到目前为止,Firefox 57 和 Edge 16 已提供支持。演示:https://fetch-abort-demo-edge.glitch.me/、https://mdn.github.io/dom-examples/abort-api/。并且存在开放的 Chrome 和 Webkit 功能错误 https://bugs.chromium.org/p/chromium/issues/detail?id=750599、https://bugs.webkit.org/show_bug.cgi?id=174980。操作方法:https://developers.google.com/web/updates/2017/09/abortable-fetch、https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples。Stack Overflow 答案中的示例位于 /sf/answers/3307543501/ (2认同)
  • 什么是缓存 API? (2认同)

Knu*_*Knu 55

  • 缺少使用内置方法来使用文档
  • 没有办法设置超时
  • 无法覆盖内容类型响应标头
  • 如果内容长度响应头存在但未暴露,则在流式传输期间,主体的总长度是未知的
  • 即使请求已经完成,也会调用信号的中止处理程序

XHR

  • 除了使用非标准标志或构造函数之外,没有办法发送cookiemozAnonAnonXMLHttpRequest
  • 无法返回FormData实例
  • 没有相当于fetchno-cors模式
  • 总是遵循重定向

  • `fetch`也缺少进度.使用XHR,您可以使用"progress"事件跟踪进度 (11认同)
  • “无法覆盖响应的内容类型标头”...这从一开始就是一个坏主意。'content-type 指示要返回的内容,并且后端应该向前端指示该内容。事实上,内容类型应该是类型的“唯一标头”,因为所请求的内容就是应该返回的内容。如果您想要从特殊子域或其他服务中获得不同的服务,以便您可以单独处理特定功能。你试图将 1% 的规则强行塞给 99% 的人。 (2认同)

Fel*_*ipe 7

上面的答案很好,并提供了很好的见解,但我在谷歌开发者博客条目中分享了相同的意见,主要区别(从实际角度来看)是从内部承诺返回的便利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();
Run Code Online (Sandbox Code Playgroud)

我们可以通过承诺和现代语法来清理并编写更简洁易读的内容

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Run Code Online (Sandbox Code Playgroud)

  • @TheOpti你可以在IE 11中填充基本的fetch支持.你也可以在许多项目中将IE11作为支持的浏览器放弃,因为许多用户群IE 11的使用率现在低于1%. (7认同)
  • @PHPGuru 作为一个在需要 IE11 支持的团队中工作了几年的人,我可以 100% 地告诉你,即使是基于 IE 代码的 Edge 也非常不同,而且比 IE11 更好用,这是一场噩梦。更重要的是,基于 Chromium 的新 Edge 本质上只是 Chrome 的重新包装,于 2020 年 1 月发布,距离您写此评论已有一年多了。对我来说真的很奇怪,人们仍然重复说 Edge 只是 IE (5认同)