Buscar API vs XMLHttpRequest

163

Eu sei que a API Fetch usa se Promiseambos permitem que você faça solicitações AJAX para um servidor.

Li que a API Fetch tem alguns recursos extras, que não estão disponíveis no XMLHttpRequest(e no polyfill da API Fetch, pois é baseado nele XHR).

Quais recursos extras a API Fetch possui?

ilyabasiuk
fonte
2
Embora eu não me lembre de imediato, há uma ou duas coisas que você pode fazer com o XHR e não pode buscar. Você diz que li que buscar tem possibilidades extras, estes artigos não são muito bons, se eles não dizem o que são
Jaromanda X
2
encontrou as duas coisas que você não pode fazer com fetch que você pode com XHR ... você não pode definir o seu próprio valor para o pedido de tempo limite em buscar, nem você pode obter eventos de progresso
Jaromanda X
3
Buscar é apenas uma maneira simplificada de fazer as coisas para a maioria dos tipos de XMLHttpRequests. Se o seu caso de uso se encaixa no que o Fetch faz, use-o. Quando você se dedica a isso, a API XMLHttpRequest é feia para o que a maioria das pessoas usa. A busca foi um esforço para oferecer uma maneira mais limpa de fazer coisas que não precisam de uma biblioteca envolvida no XMLHttpRequest para torná-la agradável.
jfriend00
1
Ele tem suporte puros de navegadores ( caniuse.com/#search=fetch ), para que haja uma polifill para ele github.com/github/fetch , wich está trabalhando acima xhr
ilyabasiuk
4
@Marco - Como você não pode dizer que fetch(url).then(function(data) (...));não é mais simples do que usar XMLHttpRequestpara fazer a mesma coisa? Pode ter muitos outros recursos, mas nossa, é mais simples de usar para coisas comuns. É uma API limpa.
jfriend00

Respostas:

120

Existem algumas coisas que você pode fazer com a busca e não com o XHR:

  • Você pode usar a API de cache com os objetos de solicitação e resposta;
  • Você pode executar no-corssolicitações, obtendo uma resposta de um servidor que não implementa o CORS. Você não pode acessar o corpo da resposta diretamente do JavaScript, mas pode usá-lo com outras APIs (por exemplo, a API de cache);
  • Respostas de streaming (com XHR, toda a resposta é armazenada em buffer na memória, com a busca, você poderá acessar o fluxo de baixo nível). Isso ainda não está disponível em todos os navegadores, mas estará disponível em breve.

Há algumas coisas que você pode fazer com o XHR que ainda não pode ser buscado, mas elas estarão disponíveis mais cedo ou mais tarde (leia o parágrafo "Futuras melhorias" aqui: https: //hacks.mozilla .org / 2015/03 / esta-api-é-tão-atraente / ):

  • Interrompa uma solicitação (agora funciona no Firefox e Edge, como @sideshowbarker explica em seu comentário);
  • Relatar progresso.

Este artigo https://jakearchibald.com/2015/thats-so-fetch/ contém uma descrição mais detalhada.

Marco
fonte
1
As especificações para a API de busca agora fornecem cancelamento. Até agora, o suporte foi enviado no Firefox 57 e Edge 16. Demonstrações: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api . E existem erros abertos do recurso Chrome & Webkit bugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 . Instruções: developers.google.com/web/updates/2017/09/abortable-fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples . E exemplo na resposta de estouro de pilha em stackoverflow.com/a/47250621/441757
sideshowbarker
1
Outra diferença é que as fetchsolicitações não podem ser reproduzidas nas Ferramentas do desenvolvedor.
Parziphal
E, pela minha experiência, fetchpode solicitar arquivos, mas o XHR não pode.
D. Pardal
64

buscar

  • faltando um método interno para consumir documentos
  • nenhuma maneira de definir um tempo limite ainda
  • não pode substituir o cabeçalho de resposta do tipo de conteúdo
  • se o cabeçalho de resposta do tamanho do conteúdo estiver presente, mas não exposto , o comprimento total do corpo será desconhecido durante a transmissão
  • chamará o manipulador de interrupção do sinal, mesmo que a solicitação tenha sido concluída
  • nenhum progresso no upload (o suporte a ReadableStreaminstâncias como corpos de solicitação ainda está por vir )

XHR

  • não há como não enviar cookies (além de usar o sinalizador não padrãomozAnon ou o AnonXMLHttpRequestconstrutor)
  • não pode retornar FormDatainstâncias
  • não tem um equivalente ao fetch's no-corsmodo de
  • siga sempre os redirecionamentos
Knu
fonte
13
fetchtambém está faltando progresso. com XHR você pode acompanhar o progresso com o progressevento
RZR
1
"não é possível substituir o cabeçalho do tipo de conteúdo da resposta" ... essa é apenas uma má idéia para começar. o tipo de conteúdo determina o que deve ser retornado e o back-end deve ditar isso ao front-end. De fato, o tipo de conteúdo deve ser o 'ÚNICO CABEÇALHO' para o tipo, porque o que é solicitado é o que deve ser retornado. Se você deseja que algo diferente sirva de um subdomínio especial ou algo assim, você pode lidar com funcionalidades específicas separadamente. Você está tentando forçar uma regra de 1% a 99% da garganta de todos.
Orubel 16/01/19
@Knu sim, e agora estamos mais avançados e podemos automatizar facilmente uma solução a 90% e deixar que os casos estranhos se direcionem para diferentes funcionalidades.
Orubel 17/01/19
1
@ RZR não exatamente, você tem Response#body.
Knu
9

As respostas acima são boas e fornecem boas informações, mas eu compartilho a mesma opinião que compartilhada nesta entrada de blog de desenvolvedores do Google em que a principal diferença (de uma perspectiva prática) é a conveniência da promessa interna retornada defetch

Em vez de ter que escrever um código como este

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

podemos limpar as coisas e escrever algo um pouco mais conciso e legível com promessas e sintaxe moderna

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Felipe
fonte
8
@TheOpti Você pode polyfill no suporte básico à busca no IE 11. Você também pode simplesmente deixar o IE11 como um navegador suportado em muitos projetos, já que em muitas bases de usuários o uso do IE 11 está abaixo de 1%.
Devon Holcombe