Javascript 获取 API 与 XMLHttpRequest

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35549547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:52:03  来源:igfitidea点击:

Fetch API vs XMLHttpRequest

javascriptajaxxmlhttprequestfetch-api

提问by ilyabasiuk

I know that Fetch API uses Promises and both of them allow you to do AJAX requests to a server.

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

I have read that Fetch API has some extra features, which aren't available in XMLHttpRequest(and in the Fetch API polyfill, since it's based on XHR).

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

What extra capabilities does the Fetch API have?

Fetch API 有哪些额外功能?

采纳答案by Marco

There are a few things that you can do with fetch and not with XHR:

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

  • You can use the Cache API with the request and response objects;
  • You can perform no-corsrequests, getting a response from a server that doesn't implement CORS. You can't access the response body directly from JavaScript, but you can use it with other APIs (e.g. the Cache API);
  • Streaming responses (with XHR the entire response is buffered in memory, with fetch you will be able to access the low-level stream). This isn't available yet in all browsers, but will be soon.
  • 您可以将缓存 API 与请求和响应对象一起使用;
  • 您可以执行no-cors请求,从未实现 CORS 的服务器获取响应。您不能直接从 JavaScript 访问响应正文,但您可以将其与其他 API(例如缓存 API)一起使用;
  • 流式响应(使用 XHR,整个响应缓冲在内存中,使用 fetch 您将能够访问低级流)。这并非在所有浏览器中都可用,但很快就会出现。

There are a couple of things that you can do with XHR that you can't do yet with fetch, but they're going to be available sooner or later (read the "Future improvements" paragraph here: https://hacks.mozilla.org/2015/03/this-api-is-so-fetching/):

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

  • Abort a request (this now works in Firefox and Edge, as @sideshowbarker explains in his comment);
  • Report progress.
  • 中止请求(现在可以在 Firefox 和 Edge 中使用,正如@sideshowbarker 在他的评论中所解释的那样);
  • 报告进展。

This article https://jakearchibald.com/2015/thats-so-fetch/contains a more detailed description.

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

回答by Knu

fetch

拿来

  • missing a builtin method to consume documents
  • no way to set a timeout yet
  • can't override the content-type response header
  • if the content-length response header is present but not exposed, the body's total length is unknown during the streaming
  • will call the signal's abort handler evenif the request has been completed
  • no upload progress (support for ReadableStreaminstances as request bodies is yet to come)
  • 缺少使用文档的内置方法
  • 没有办法设置超时
  • 无法覆盖内容类型响应标头
  • 如果 content-length 响应头存在但未公开,则在流传输期间主体的总长度未知
  • 即使请求已完成,也会调用信号的中止处理程序
  • 没有上传进度(对ReadableStream请求主体的支持尚未到来

XHR

XHR

  • there's no way to notsend cookies (apart from using the non-standard mozAnonflagor the AnonXMLHttpRequestconstructor)
  • can't return FormDatainstances
  • doesn't have an equivalent to fetch's no-corsmode
  • always follow redirects
  • 没有办法发送 cookie(除了使用非标准mozAnon标志AnonXMLHttpRequest构造函数)
  • 无法返回FormData实例
  • 没有等效于fetchno-cors模式
  • 始终遵循重定向

回答by Felipe

The answers above are good and provide good insights, but I share the same opinion as shared in this google developers blog entryin that the main difference (from a practical perspective) is the convenience of the built-in promise returned from fetch

上面的答案很好,提供了很好的见解,但我与这篇google 开发者博客文章中的观点相同,主要区别(从实际角度来看)是从返回的内置承诺的便利性fetch

Instead of having to write code like this

而不是必须编写这样的代码

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();

we can clean things up and write something a little more concise and readable with promises and modern syntax

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

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });