提取API与XMLHttpRequest


163

我知道Fetch API使用,Promise并且两者都允许您向服务器执行AJAX请求。

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

Fetch API有哪些额外功能?


2
尽管我不记得当场,但是使用XHR可以完成一两件事,而使用fetch无法完成。您说您已经读过fetch具有更多的可能性,那些文章如果不说出它们的意思就不是很好
Jaromanda X

2
发现了XHR无法完成的两件事……您无法为获取中的请求超时设置自己的值,也无法获取进度事件
Jaromanda X

3
对于大多数类型的XMLHttpRequest而言,访存只是一种简化的处理方式。如果您的用例适合Fetch的用途,请使用它。深入了解它之后,对于大多数人而言,XMLHttpRequest API很难理解。Fetch的目的是提供一种更清洁的处理方式,不需要将XMLHttpRequest包裹起来的库即可使用。
jfriend00

1
它在浏览器(支持纯caniuse.com/#search=fetch),所以有polifill它github.com/github/fetch,至极正在上面XHR
ilyabasiuk

4
@Marco-您怎能说这fetch(url).then(function(data) (...));不比使用XMLHttpRequest做同一件事简单?它可能还具有许多其他功能,但是,geez,它肯定更易于用于普通事物。这是一个清理过的API。
jfriend00

Answers:


120

您可以使用fetch而不是XHR进行以下操作:

  • 您可以将Cache API与请求和响应对象一起使用;
  • 您可以执行no-cors请求,并从未实现CORS的服务器获得响应。您不能直接从JavaScript访问响应主体,但可以将其与其他API(例如Cache API)一起使用;
  • 流式响应(使用XHR,整个响应将被缓存在内存中,通过访存,您将能够访问低级流)。目前尚不能在所有浏览器中使用此功能,但很快就会发布。

您可以使用XHR进行一些尚无法使用的操作,但是迟早它们将可用(请在此处阅读“未来的改进”部分:https://hacks.mozilla .org / 2015/03 / this-api-is-so-fetching /):

  • 中止请求(此操作现在在Firefox和Edge中有效,如@sideshowbarker在评论中所述);
  • 报告进度。

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



1
另一个区别是fetch请求无法在开发人员工具上重播。
Parziphal

而且,根据我的经验,fetch可以请求文件,但是XHR不能。
D. Pardal,

64

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

XHR

  • 没有方法发送cookie(除了使用非标准mozAnon标志AnonXMLHttpRequest构造函数)
  • 无法返回FormData实例
  • 没有等效于fetchno-cors模式
  • 始终遵循重定向

13
fetch也缺少进展。使用XHR,您可以跟踪progress事件的进度
rzr

1
“无法覆盖响应的内容类型标头” ...刚开始这是一个坏主意。“内容类型”指示要返回的内容,而“后端”则应指示要返回的内容。实际上,内容类型应该是类型的“唯一标头”,因为请求的是应该返回的内容。如果您想从一个特殊的子域中获得不同的服务或其他东西,以便可以单独处理特定的功能。您试图迫使1%的规则压倒所有人的99%的喉咙。
Orubel

@Knu是的,现在我们更加先进了,我们可以轻松实现90%解决方案的自动化,并将异常情况路由到其他功能。
Orubel

1
@rzr不完全是,您知道了Response#body
KNU

9

上面的答案是好的,并且提供了很好的见解,但是我与这个Google开发者博客条目中的观点相同,因为主要的区别(从实际角度出发)是从中返回内置承诺的便利性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) => { ... });

8
@TheOpti您可以在IE 11中添加基本的获取支持。您也可以将IE11作为许多项目中受支持的浏览器,因为许多用户群中IE 11的使用率现在低于1%。
Devon Holcombe '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.