XMLHttpRequest - XMLHttpRequest

XMLHttpRequest ( XHR ) é uma API na forma de um objeto cujos métodos transferem dados entre um navegador da web e um servidor da web . O objeto é fornecido pelo ambiente JavaScript do navegador . Particularmente, a recuperação de dados de XHR com o propósito de modificar continuamente uma página da web carregada é o conceito subjacente de design Ajax . Apesar do nome, o XHR pode ser usado com protocolos diferentes de HTTP e os dados podem estar na forma não apenas de XML , mas também de JSON , HTML ou texto simples .

WHATWG mantém um padrão XHR como um documento vivo . O trabalho em andamento no W3C para criar uma especificação estável é baseado em instantâneos do padrão WHATWG.

História

O conceito por trás do objeto XMLHttpRequest foi originalmente criado pelos desenvolvedores do Outlook Web Access (pela Microsoft) para o Microsoft Exchange Server 2000 . Uma interface chamada IXMLHTTPRequest foi desenvolvida e implementada na segunda versão da biblioteca MSXML usando este conceito. A segunda versão da biblioteca MSXML foi enviada com o Internet Explorer 5.0 em março de 1999, permitindo acesso, via ActiveX , à interface IXMLHTTPRequest usando o wrapper XMLHTTP da biblioteca MSXML.

As versões 5 e 6 do Internet Explorer não definiam o identificador de objeto XMLHttpRequest em suas linguagens de script, pois o próprio identificador XMLHttpRequest não era padrão na época de seus lançamentos. A compatibilidade com versões anteriores pode ser alcançada por meio da detecção de objeto se o identificador XMLHttpRequest não existir. A Microsoft adicionou o identificador de objeto XMLHttpRequest às suas linguagens de script no Internet Explorer 7.0 lançado em outubro de 2006.

O projeto Mozilla desenvolveu e implementou uma interface chamada nsIXMLHttpRequest no motor de layout Gecko . Essa interface foi modelada para funcionar o mais próximo possível da interface IXMLHTTPRequest da Microsoft . A Mozilla criou um wrapper para usar essa interface por meio de um objeto JavaScript que eles chamaram de XMLHttpRequest . O objeto XMLHttpRequest estava acessível já no Gecko versão 0.6 lançado em 6 de dezembro de 2000, mas não era completamente funcional até a versão 1.0 do Gecko lançado em 5 de junho de 2002. O objeto XMLHttpRequest tornou-se um padrão de facto em outras grandes clientes da web, implementados no Safari 1.2 lançado em fevereiro de 2004, Konqueror , Opera 8.0 lançado em abril de 2005 e iCab 3.0b352 lançado em setembro de 2005.

Com o advento de bibliotecas JavaScript para vários navegadores, como jQuery , os desenvolvedores podem invocar a funcionalidade XMLHttpRequest indiretamente.

Padrões

O World Wide Web Consortium publicou uma especificação de Working Draft para o objeto XMLHttpRequest em 5 de abril de 2006, editada por Anne van Kesteren da Opera Software e Dean Jackson do W3C. Seu objetivo é "documentar um conjunto mínimo de recursos interoperáveis ​​com base nas implementações existentes, permitindo que os desenvolvedores da Web usem esses recursos sem código específico da plataforma".

O W3C também publicou outra especificação de Working Draft para o objeto XMLHttpRequest , "XMLHttpRequest Level 2", em 25 de fevereiro de 2008. O nível 2 consiste em funcionalidade estendida para o objeto XMLHttpRequest , incluindo, mas não se limitando a, eventos de progresso, suporte para cross- solicitações de site e o tratamento de fluxos de bytes. No final de 2011, a especificação de Nível 2 foi abandonada e absorvida pela especificação original.

No final de 2012, o WHATWG assumiu o desenvolvimento e mantém um padrão de vida usando Web IDL . Os rascunhos atuais do W3C são baseados em instantâneos do padrão WHATWG .

Solicitação HTTP

As seções a seguir demonstram como uma solicitação usando o objeto XMLHttpRequest funciona em um agente de usuário em conformidade com base no W3C Working Draft. Como o padrão W3C para o objeto XMLHttpRequest ainda é um rascunho, os agentes do usuário não podem cumprir todos os funcionamentos da definição W3C e qualquer um dos itens a seguir está sujeito a alterações. Extremo cuidado deve ser levado em consideração ao criar scripts com o objeto XMLHttpRequest em vários agentes de usuário. Este artigo tentará listar as inconsistências entre os principais agentes do usuário.

O método aberto

As solicitações HTTP e HTTPS do objeto XMLHttpRequest devem ser inicializadas por meio do método aberto . Este método deve ser chamado antes do envio real de uma solicitação para validar e resolver o método de solicitação, URL e informações do usuário URI a serem usadas para a solicitação. Este método não garante que o URL exista ou que as informações do usuário estejam corretas. Este método pode aceitar até cinco parâmetros , mas requer apenas dois, para inicializar uma solicitação.

open( Method, URL, Asynchronous, UserName, Password )

O primeiro parâmetro do método é uma string de texto que indica o método de solicitação HTTP a ser usado. Os métodos de solicitação que devem ser suportados por um agente de usuário em conformidade , definidos pelo rascunho W3C para o objeto XMLHttpRequest, estão listados atualmente como a seguir.

  • GET (compatível com Internet Explorer 7 +, Mozilla 1+ )
  • POST (compatível com IE7 +, Mozilla 1+)
  • HEAD (compatível com IE7 +)
  • POR
  • EXCLUIR
  • OPÇÕES (compatível com IE7 +)

No entanto, os métodos de solicitação não se limitam aos listados acima. O rascunho do W3C afirma que um navegador pode oferecer suporte a métodos de solicitação adicionais a seu próprio critério.

O segundo parâmetro do método é outra string de texto , esta indicando a URL da solicitação HTTP. O W3C recomenda que os navegadores gerem um erro e não permitam a solicitação de um URL com uma porta diferente ou com o componente URI ihost do documento atual.

O terceiro parâmetro, um valor booleano que indica se a solicitação será ou não assíncrona, não é um parâmetro exigido pelo rascunho do W3C. O valor padrão deste parâmetro deve ser considerado verdadeiro por um agente de usuário em conformidade com W3C, se não for fornecido. Uma solicitação assíncrona ("verdadeiro") não aguardará uma resposta do servidor antes de continuar com a execução do script atual. Em vez disso, ele invocará o ouvinte de evento onreadystatechange do objeto XMLHttpRequest em todos os estágios da solicitação. Uma solicitação síncrona ("false"), entretanto, bloqueará a execução do script atual até que a solicitação seja concluída, não invocando o ouvinte de evento onreadystatechange . Observe que a partir do Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), Blink 39.0 (Chrome) e Edge 13, as solicitações síncronas no thread principal foram descontinuadas devido ao seu impacto negativo na experiência do usuário, pois podem causar congelamento da IU enquanto o thread executa a solicitação.

O quarto e o quinto parâmetros são o nome de usuário e a senha , respectivamente. Esses parâmetros, ou apenas o nome de usuário, podem ser fornecidos para autenticação e autorização se exigidos pelo servidor para esta solicitação.

var xmlhttp;

if (window.XMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", filepath, false);
    xmlhttp.send(null);
}

O método setRequestHeader

Após a inicialização bem-sucedida de uma solicitação, o método setRequestHeader do objeto XMLHttpRequest pode ser chamado para enviar cabeçalhos HTTP com a solicitação.

setRequestHeader( Name, Value )

O primeiro parâmetro deste método é o nome da string de texto do cabeçalho. O segundo parâmetro é o valor da string de texto. Este método deve ser chamado para cada cabeçalho que precisa ser enviado com a solicitação. Todos os cabeçalhos anexados aqui serão removidos na próxima vez que o método aberto for chamado em um agente de usuário em conformidade com W3C.

O método de envio

Para enviar uma solicitação HTTP, o método send do XMLHttpRequest deve ser chamado. Este método aceita um único parâmetro contendo o conteúdo a ser enviado com a solicitação.

send( Data )

Este parâmetro pode ser omitido se nenhum conteúdo precisar ser enviado. O rascunho do W3C afirma que esse parâmetro pode ser de qualquer tipo disponível para a linguagem de script, desde que possa ser transformado em uma string de texto, com exceção do objeto de documento DOM . Se um agente do usuário não puder serializar o parâmetro, o parâmetro deve ser ignorado. No entanto, o Firefox 3.0.xe as versões anteriores lançarão uma exceção se sendfor chamado sem um argumento.

Se o parâmetro for um objeto de documento DOM , um agente do usuário deve garantir que o documento seja transformado em XML bem formado usando a codificação indicada pela propriedade inputEncoding do objeto de documento . Se o cabeçalho da solicitação Content-Type ainda não foi adicionado por meio de setRequestHeader , ele deve ser adicionado automaticamente por um agente de usuário em conformidade como "application / xml; charset = charset ", onde charset é a codificação usada para codificar o documento.

Se o agente do usuário estiver configurado para usar um servidor proxy , o objeto XMLHttpRequest modificará a solicitação de forma apropriada para se conectar ao proxy em vez do servidor de origem e enviará os Proxy-Authorizationcabeçalhos conforme configurados.

O ouvinte de evento onreadystatechange

Se o método open do objeto XMLHttpRequest foi chamado com o terceiro parâmetro definido como true para uma solicitação assíncrona, o ouvinte de evento onreadystatechange será chamado automaticamente para cada uma das seguintes ações que alteram a propriedade readyState do objeto XMLHttpRequest.

Mudanças de estado funcionam assim:

  • Descrição do estado
   0		The request is not initialized.
   1		The request has been set up.
   2		The request has been sent.
   3		The request is in process.
   4		The request is completed.
  • Depois que o método open foi chamado com sucesso, a propriedade readyState do objeto XMLHttpRequest deve receber o valor 1 (OPENED).
  • Depois que o método send foi chamado e os cabeçalhos de resposta HTTP foram recebidos, a propriedade readyState do objeto XMLHttpRequest deve receber um valor 2 (HEADERS_RECEIVED).
  • Depois que o conteúdo da resposta HTTP começa a carregar, a propriedade readyState do objeto XMLHttpRequest deve receber o valor 3 (LOADING).
  • Assim que o conteúdo da resposta HTTP terminar de carregar, a propriedade readyState do objeto XMLHttpRequest deve receber o valor 4 (DONE).

O ouvinte responderá apenas às mudanças de estado que ocorrerem depois que o ouvinte for definido. Para detectar os estados 1 e 2, o ouvinte deve ser definido antes que o método aberto seja chamado. O método aberto deve ser chamado antes que o método send seja chamado.

var request = new XMLHttpRequest();
request.onreadystatechange = function () {
    var DONE = this.DONE || 4;
    if (this.readyState === DONE){
        alert(this.readyState);
    }
};
request.open('GET', 'somepage.xml', true);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');  // Tells server that this call is made for ajax purposes.
                                                                 // Most libraries like jQuery/Prototype/Dojo do this
request.send(null);  // No data needs to be sent along with the request.

A resposta HTTP

Após uma chamada bem-sucedida e concluída para o método send do XMLHttpRequest, se a resposta do servidor for XML bem formado e o cabeçalho Content-Type enviado pelo servidor for entendido pelo agente do usuário como um tipo de mídia da Internet para XML, a propriedade responseXML do objeto XMLHttpRequest conterá um objeto de documento DOM. Outra propriedade, responseText , conterá a resposta do servidor em texto simples por um agente do usuário em conformidade, independentemente de ter sido ou não entendido como XML.

Solicitações de vários domínios

No início do desenvolvimento da World Wide Web , foi possível violar a segurança dos usuários pelo uso de JavaScript para trocar informações de um site com outro menos confiável. Todos os navegadores modernos, portanto, implementam uma política de mesma origem que impede muitos desses ataques, como scripts entre sites . Os dados XMLHttpRequest estão sujeitos a esta política de segurança, mas às vezes os desenvolvedores da web desejam contornar intencionalmente suas restrições. Isso às vezes se deve ao uso legítimo de subdomínios, como, por exemplo, fazer um XMLHttpRequest a partir de uma página criada por foo.example.compara obter informações de bar.example.comnormalmente falhará.

Existem várias alternativas para contornar esse recurso de segurança, incluindo o uso de JSONP , Cross-Origin Resource Sharing (CORS) ou alternativas com plug-ins como Flash ou Silverlight (ambos agora obsoletos). XMLHttpRequest de origem cruzada é especificado na especificação XMLHttpRequest Nível 2 do W3C. O Internet Explorer não implementou CORS até a versão 10. As duas versões anteriores (8 e 9) ofereciam funcionalidade semelhante por meio da API XDomainRequest (XDR). CORS agora é compatível com todos os navegadores modernos (desktop e celular).

O protocolo CORS possui várias restrições, com dois modelos de suporte. O modelo simples não permite definir cabeçalhos de solicitação personalizados e omite cookies . Além disso, apenas os métodos de solicitação HEAD, GET e POST são suportados, e POST permite apenas os seguintes tipos de MIME : "text / plain", "application / x-www-urlencoded" e " multipart / form-data ". Apenas "text / plain" era inicialmente suportado. O outro modelo detecta quando um dos recursos não simples é solicitado e envia uma solicitação pré-voo ao servidor para negociar o recurso.

Buscar alternativa

O fluxo do programa usando retornos de chamada XHR assíncronos pode apresentar dificuldade de legibilidade e manutenção. ECMAScript 2015 (ES6) adicionou a construção de promessa para simplificar a lógica assíncrona. Desde então, os navegadores implementaram a fetch()interface alternativa para obter a mesma funcionalidade do XHR usando promessas em vez de retornos de chamada.

A busca também é padronizada pelo WHATWG.

Veja também

Referências

links externos