{"id":12,"date":"2007-10-03T11:32:59","date_gmt":"2007-10-03T18:32:59","guid":{"rendered":"http:\/\/www.milfont.org\/tech\/2007\/10\/03\/destilando-o-xmlhttprequest\/"},"modified":"2021-12-15T17:25:00","modified_gmt":"2021-12-15T20:25:00","slug":"destilando-o-xmlhttprequest","status":"publish","type":"post","link":"https:\/\/www.milfont.org\/tech\/2007\/10\/03\/destilando-o-xmlhttprequest\/","title":{"rendered":"Destilando o XMLHttpRequest"},"content":{"rendered":"<p>O modelo que passou a ser conhecido como <a href=\"http:\/\/en.wikipedia.org\/wiki\/AJAX\">Ajax<\/a>, termo criado por <a href=\"http:\/\/blog.jjg.net\/\">Jesse James Garrett<\/a>, ficou famoso ap\u00f3s o lan\u00e7amento do GMail, a capacidade de obter recursos remotos sem precisar dar um refresh na p\u00e1gina, modificou toda a forma de pensar no desenvolvimento web. A interface de usu\u00e1rio sa\u00eda de uma estrutura puramente est\u00e1tica e passou a ser semelhante ao ambiente desktop.<\/p>\n<p>Sua implementa\u00e7\u00e3o \u00e9 poss\u00edvel por causa do objeto javascript<a href=\"http:\/\/www.w3.org\/TR\/XMLHttpRequest\/\"> XMLHttpRequest<\/a> que faz uma conex\u00e3o ass\u00edncrona ao servidor e permite que o usu\u00e1rio continue seu trabalho sem bloquear a p\u00e1gina. Na \u00e9poca n\u00e3o era especificado ainda pelo W3C.<\/p>\n<p>O XMLHttpRequest surgiu como uma <a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/xmlsdk\/html\/63409298-0516-437d-b5af-68368157eae3.asp\">implementa\u00e7\u00e3o propriet\u00e1ria da Microsoft<\/a> e posteriormente criado no <a href=\"http:\/\/developer.mozilla.org\/en\/docs\/XMLHttpRequest\">Mozilla em 2002<\/a>, logo seguido pelos demais Browsers. A <a href=\"http:\/\/www.w3.org\/TR\/XMLHttpRequest\/#xmlhttprequest\">interface<\/a> definida pelo W3C ser\u00e1 o objeto de estudo desse artigo.<\/p>\n<p>Uma conex\u00e3o remota de forma ass\u00edncrona segue o seguinte esquema:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.milfont.org\/tech\/wp-content\/uploads\/2007\/10\/request_ajax.gif\" alt=\"request_ajax.gif\"><\/p>\n<ol>\n<li>Um evento \u00e9 disparado para dar in\u00edcio a execu\u00e7\u00e3o;<\/li>\n<li>Um objeto XMLHttpRequest \u00e9 criado e configurado;<\/li>\n<li>Uma requisi\u00e7\u00e3o de um recurso \u00e9 feita para o servidor;<\/li>\n<li>O servidor realizada sua l\u00f3gica de neg\u00f3cio e devolve o recurso na forma de texto comum (que deve ser um xml em formado);<\/li>\n<li>Uma fun\u00e7\u00e3o de callback, previamente informada, manipula os dados retornados;<\/li>\n<li>A renderiza\u00e7\u00e3o ao usu\u00e1rio \u00e9 realizada.<\/li>\n<\/ol>\n<p>A cria\u00e7\u00e3o e configura\u00e7\u00e3o do objeto, como o envio de requisi\u00e7\u00e3o pelo XMLHttpRequest para a captura de um recurso remoto segue os seguintes passos:<\/p>\n<pre lang=\"javascript\">\/\/instancia um novo objeto\nvar ajax = new XMLHttpRequest();\n\/\/Configura uma function para a manipula\u00e7\u00e3o\n\/\/da reposta\najax.onreadystatechange = handler;\n\/\/abre a conex\u00e3o\najax.open(\"GET\", \"test.xml\");\n\/\/envia a requisi\u00e7\u00e3o\najax.send();\n<\/pre>\n<p>Caso a conex\u00e3o seja pelo m\u00e9todo &#8220;POST&#8221;, o m\u00e9todo send recebe como par\u00e2metro, as vari\u00e1veis a serem enviadas.<\/p>\n<h3>Cria\u00e7\u00e3o do objeto<\/h3>\n<p>A Microsoft s\u00f3 implementou a interface XMLHttpRequest como um objeto nativo a partir do Internet Explorer 7, antes disso o objeto era um ActiveX. Apesar que os m\u00e9todos e propriedades haviam sido copiados desse ActiveX, garantindo o funcionamento id\u00eantico a todos os Browsers que suportam o XMLHttpRequest.<\/p>\n<p>Ent\u00e3o para as vers\u00f5es anteriores do IE, h\u00e1 a necessidade de cria\u00e7\u00e3o customizada, eis:<\/p>\n<pre lang=\"javascript\">    var http;\n    try {\n\t    \/\/cria o objeto caso o Browser\n        \/\/seja compat\u00edvel com o W3C\n        http = new XMLHttpRequest();\n    } catch(e) {\n        \/\/caso IE &lt; IE7\n        \/\/array com vers\u00f5es conhecidas\n        \/\/de implementa\u00e7\u00f5es do ActiveX\n        var msxml = [\n                   'MSXML2.XMLHTTP.3.0', \n                   'MSXML2.XMLHTTP', \n                   'Microsoft.XMLHTTP'];\n        for ( var i=0, len = msxml.length; i &lt; len; ++i ) {\n            try {\n                \/\/varre o array at\u00e9 identificar qual ActiveX\n                http = new ActiveXObject(msxml[i]); break;\n            } catch(e) {}\n        }\n    }\n<\/pre>\n<h3>Conhecendo a Interface<\/h3>\n<p>Representa\u00e7\u00e3o da Interface<\/p>\n<pre lang=\"javascript\">interface XMLHttpRequest {\n  \/\/ event handler\n  attribute EventListener onreadystatechange;\n  \/\/ state\n  const unsigned short UNSENT = 0;\n  const unsigned short OPEN = 1;\n  const unsigned short SENT = 2;\n  const unsigned short LOADING = 3;\n  const unsigned short DONE = 4;\n  readonly attribute unsigned short readyState;\n  \/\/ request\n  void open(in DOMString method, in DOMString url);\n  void open(in DOMString method, in DOMString url, \n            in boolean async);\n  void open(in DOMString method, in DOMString url, \n            in boolean async, in DOMString user);\n  void open(in DOMString method, in DOMString url, \n            in boolean async, in DOMString user, \n            in DOMString password);\n  void setRequestHeader(in DOMString header, in DOMString value);\n  void send();\n  void send(in DOMString data);\n  void send(in Document data);\n  void abort();\n  \/\/ response\n  DOMString getAllResponseHeaders();\n  DOMString getResponseHeader(in DOMString header);\n  readonly attribute DOMString responseText;\n  readonly attribute Document responseXML;\n  readonly attribute unsigned short status;\n  readonly attribute DOMString statusText;\n};<\/pre>\n<h4>Event Listener<\/h4>\n<p>A Interface XMLHttpRequest possui um EventListener denominado &#8220;<strong>onreadystatechange<\/strong>&#8220;, que \u00e9 um manipulador de eventos que \u00e9 invocado quando o evento readystatechange \u00e9 acionado. Passamos uma fun\u00e7\u00e3o de tratamento a esse EventListener que verificar\u00e1 os estados da conex\u00e3o.<\/p>\n<pre lang=\"javascript\">\/\/obtem uma instancia\nvar ajax = new XMLHttpRequest();\n\/\/seta o EventListener com o handler\najax.onreadystatechange = function() {\n    \/\/testa se j\u00e1 recebeu e foi com sucesso\n    if(this.readyState == 4  &amp;&amp; this.status == 200) {\n        \/\/obtem o xml enviado pelo servidor\n        var xml = this.responseXML;\n    }\n};\n<\/pre>\n<h4>Propriedades<\/h4>\n<p>A Interface possui uma propriedade denominada &#8220;<strong>readyState<\/strong>&#8221; que recebe o valor de uma constante que representa o estado atual da conex\u00e3o. As constantes que representam os estados s\u00e3o definidos como:<\/p>\n<ol>\n<li>UNSENT = 0; \/\/Apenas instanciado<\/li>\n<li>OPEN = 1; \/\/aberta<\/li>\n<li>SENT = 2; \/\/enviada<\/li>\n<li>LOADING = 3; \/\/abrindo<\/li>\n<li>DONE = 4; \/\/realizada<\/li>\n<\/ol>\n<p>A propriedade &#8220;<strong>status<\/strong>&#8221; da Interface, representa o c\u00f3digo de status do protocolo HTTP enviado pelo servidor, como o c\u00f3digo &#8220;200&#8221; para uma requisi\u00e7\u00e3o com sucesso. Caso o recurso n\u00e3o esteja dispon\u00edvel, \u00e9 lan\u00e7ado uma exce\u00e7\u00e3o INVALID_STATE_ERR pelo Browser. A lista de &#8220;<a href=\"http:\/\/www.w3.org\/Protocols\/rfc2616\/rfc2616-sec10.html\">HTTP Status Code<\/a>&#8221; voc\u00ea encontra <a href=\"http:\/\/en.wikipedia.org\/wiki\/List_of_HTTP_status_codes\">aqui<\/a>.<\/p>\n<p>A propriedade &#8220;<strong>statusText<\/strong>&#8220;, \u00e9 a mensagem texto do &#8220;HTTP status code&#8221;, e \u00e9 recebida logo ap\u00f3s ele, como &#8220;Not Found&#8221; para o &#8220;status code&#8221; 404, que indica que o recurso n\u00e3o foi encontrado no servidor de destino.<\/p>\n<p>As propriedades &#8220;<strong>responseText<\/strong>&#8221; e &#8220;<strong>responseXML<\/strong>&#8220;, devolvem a resposta do servidor na forma de uma DOMString (texto) e Document (da especifica\u00e7\u00e3o DOM) respectivamente, em outras palavras, devolve um texto puro no caso do responseText ou um xml parseado no caso do responseXML.<\/p>\n<h4>M\u00e9todos<\/h4>\n<p>O m\u00e9todo &#8220;<strong>abort<\/strong>&#8221; cancela a requisi\u00e7\u00e3o, entretanto ele percorre uma s\u00e9rie de atividades dependendo do estado da requisi\u00e7\u00e3o no momento que \u00e9 invocado. Para uma explana\u00e7\u00e3o mais apropriada no mecanismo que o abort realizada, visite esse <a href=\"http:\/\/www.w3.org\/TR\/XMLHttpRequest\/#dfn-abort\">link da especifica\u00e7\u00e3o da Interface<\/a>.<\/p>\n<p>O m\u00e9todo &#8220;<strong>open<\/strong>&#8221; \u00e9 overloaded na Interface, apesar de <a href=\"http:\/\/www.milfont.org\/tech\/2007\/10\/01\/overloading-e-overriding-no-javascript\/\">n\u00e3o existir overloading em javascript<\/a>. Leve em considera\u00e7\u00e3o que \u00e9 um s\u00f3, na implementa\u00e7\u00e3o o n\u00famero de argumentos passados tem a ver com a funcionalidade dependente do m\u00e9todo, exemplo, os par\u00e2metros &#8220;user&#8221; e &#8220;password&#8221; s\u00e3o necess\u00e1rios apenas no caso de url restrita no servidor, e caso o par\u00e2metro &#8220;async&#8221; n\u00e3o seja definido, a conex\u00e3o \u00e9 ass\u00edncrona por default. Os primeiro par\u00e2metro representa o m\u00e9todo <a href=\"http:\/\/ietf.org\/rfc\/rfc2616\">HTTP de requisi\u00e7\u00e3o<\/a>, que pode ser dos tipos: POST, GET, PUT, HEAD, DELETE e OPTIONS. O segundo par\u00e2metro \u00e9 a url que receber\u00e1 a requisi\u00e7\u00e3o, o terceiro, quarto e quinto s\u00e3o opcionais como j\u00e1 falado.<\/p>\n<p>O m\u00e9todo &#8220;<strong>setRequestHeader<\/strong>&#8221; \u00e9 usado antes do m\u00e9todo &#8220;<strong>send<\/strong>&#8221; e habilita enviar informa\u00e7\u00f5es de cabe\u00e7alho na requisi\u00e7\u00e3o quando for disparado os recursos ao servidor.<\/p>\n<p>O m\u00e9todo &#8220;<strong>send<\/strong>&#8221; envia a requisi\u00e7\u00e3o com o argumento opcional &#8220;data&#8221; que \u00e9 do tipo &#8220;Text&#8221; ou &#8220;Document&#8221;.<\/p>\n<p>Quando o m\u00e9todo de requisi\u00e7\u00e3o escolhido \u00e9 o GET, os argumentos a serem enviados ao servidor \u00e9 usado no par\u00e2metro &#8220;url&#8221;, como &#8220;\/pagina.jsp?id=1&amp;nome=milfont&#8221;. J\u00e1 no m\u00e9todo POST, os dados ser\u00e3o enviados como argumento do m\u00e9todo &#8220;send&#8221;<\/p>\n<h4>C\u00f3digo completo de uma submiss\u00e3o Ajax<\/h4>\n<pre lang=\"javascript\">    var http;\n    try {\n        http = new XMLHttpRequest();\n    } catch(e) {\n        var msxml = [\n                   'MSXML2.XMLHTTP.3.0', \n                   'MSXML2.XMLHTTP', \n                   'Microsoft.XMLHTTP'];\n        for ( var i=0, len = msxml.length; i &lt; len; ++i ) {\n            try {\n                http = new ActiveXObject(msxml[i]); break;\n            } catch(e) {}\n        }\n    }\n    http.onreadystatechange = function() {\n        if(this.readyState == 4  &amp;&amp; this.status == 200) {\n           var xml = this.responseXML;\n        }\n    };\n    var params = \"id=1&amp;name=milfont\";\n    http.open(\"POST\", \"pagina.jsp\");\n    http.setRequestHeader(\"Content-type\", \n\t                  \"application\/x-www-form-urlencoded\");\n    http.setRequestHeader(\"Content-length\", params.length);\n    http.setRequestHeader(\"Connection\", \"close\");\n    http.send(params);\n<\/pre>\n<p>Para mais features nas pr\u00f3ximas vers\u00f5es da especifica\u00e7\u00e3o mas que j\u00e1 podem existir nas implementa\u00e7\u00f5es, <a href=\"http:\/\/www.w3.org\/TR\/XMLHttpRequest\/#notcovered\">visite esse link<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>O modelo que passou a ser conhecido como Ajax, termo criado por Jesse James Garrett, ficou famoso ap\u00f3s o lan\u00e7amento do GMail, a capacidade de obter recursos remotos sem precisar dar um refresh na p\u00e1gina, modificou toda a forma de pensar no desenvolvimento web. A interface de usu\u00e1rio sa\u00eda de uma estrutura puramente est\u00e1tica e [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,23,29],"tags":[],"_links":{"self":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts\/12"}],"collection":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":2,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts\/12\/revisions"}],"predecessor-version":[{"id":1908,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/posts\/12\/revisions\/1908"}],"wp:attachment":[{"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/media?parent=12"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/categories?post=12"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.milfont.org\/tech\/wp-json\/wp\/v2\/tags?post=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}