Dica Rápida – Requisições Ajax Avançadas com jQuery
Hoje vou mostrar uma dica rápida e avançada que pode te ajudar a manter seus sistema mais seguros, quando se trabalha com Ajax. Irei desenvolver encima do PHP e do jQuery, mas a dica vale para qualquer biblioteca (PHP, ASP…) e framework (jQuery, Mootools…), inclusive se for na mão mesmo, sem framework.
Quando o jQuery faz uma requisição em Ajax, é passado um cabeçalho header com a seguinte variável:
$_SERVER['HTTP_X_REQUESTED_WITH']
E a partir dai, muita gente faz até uma função para checar se a requisição é ajax e alterar o comportamento do sistema de acordo com o resultado:
/** * Checa se é uma requisição em ajax através do cabeçalho header * @return boolean */ function checkAjax(){ return (isset($_SERVER['HTTP_X_REQUESTED_WITH']))? TRUE : FALSE; }
Até ai tudo bem… mas o que quero mostrar é porque que com o jQuery, há esse cabeçalho adicional, e como podemos adicionar novos cabeçalhos com Javascript. Vamos lá:
No momento em que é feita a requisição Ajax com jQuery é feita uma série de processos para definir como será a requisição, se é JSON, HTML, XML e tudo mais, e para grande parte desse processo o jQuery trabalha o header da requisição para se encaixar no modelo da requisição pedida.
No caso do cabeçalho HTTP_X_REQUESTED_WITH, jQuery provê este parâmetro independente do modelo da requisição – é padrão do jQuery não de requisições em Ajax, então, em uma requisição normal (sem framework) é bem provável que não tenha esta cabeçalho.
Se você buscar no código fonte irá ver que é o bloco de código responsável por criar o cabeçalho personalizado é este:
// Set header so the called script knows that it's an XMLHttpRequest // Only send the header if it's not a remote XHR if ( !remote ) { xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); }
E assim você recebe o cabeçalho adicional na requisição…
Criando novos cabeçalhos na requisição
Para isto, no jQuery usamos o callback beforeSend que nos permitirá criar novos cabeçalhos. Vale lembrar aqui, que no PHP você recebe o cabeçalho em caixa alta, com o caractere “-” trocado pelo caractere “_”, e sempre irá começar com HTTP:
$.ajax({ type: 'POST', url: 'algum-arqiuvo.php', beforeSend: function(xhr){ //Observe o parâmetro na função xhr.setRequestHeader('X-Parametro', 'Valor-Parametro'); //Mágica aqui } });
O callback beforeSend está disponível apenas na função $.ajax() e em $.ajaxSetup(), então tome cuidado com as funções $.get(), $.post()…
Um exemplo rápido:
/** * Requisição com uma cabeçalho personalizado * Envia o nome do usuário e retorna se é o nome certo */ $.ajax({ type: 'GET', url: 'checa-nome.php', beforeSend: function(xhr){ xhr.setRequestHeader('X-Nome', 'Mateus'); } sucess: function(data){ alert(data); } });
e no PHP:
<?php //arquivo checa-nome.php if(isset($_SERVER['HTTP_X_NOME']) AND $_SERVER['HTTP_X_NOME'] == 'Mateus'){ echo "Nome correto!"; }else{ echo "Nome incorreto! O sistema se auto-destruirá em 4 segundos...4. 3. 2. 1!!!!"; } ?>
A função .setRequestHeader() é nativa do Javascript, por isso é funcional em código js. Você pode ver mais detalhes sobre ela clicando aqui.
E assim você pode criar novos cabeçalhos, para trazer mais segurança ou seja lá o que você tiver em mente. Espero que tenham entendido… qualquer dúvida mande um comentário!
Até a próxima.
4 Comentários
Tiago César Oliveira disse:
11 de novembro de 2010 às 21:51
Não entendi somente a vantagem que esse método poderia ter sobre, digamos, a passagem de um parâmetro normal (via GET ou POST – um campo de formulário, por exemplo).
Qual a diferença entre passar um valor no cabeçalho ou em uma variável GET ou POST? Há alguma vantagem no primeiro método?
Mateus Souza disse:
11 de novembro de 2010 às 22:43
Ai depende do caso… porque tem coisas que “não dá” pra ficar passando via GET ou POST; grande exemplo disto é o cabeçalho que o jQuery envia!
Acredito eu que também é mais seguro o primeiro método, porque a manipulação dele é mais dificil pro usuário…
Resumidamente, eu vejo assim:
Se eu preciso de um dado valor, em cada página que for requisitada, usar o cabeçalho é indiscutivelmente melhor, porque não requer nenhuma submissão e tal. Agora já em um formulário o negocio é totalmente diferente… POST ou GET sempre será a melhor opção.
Entendeste?
André D. Molin disse:
11 de novembro de 2010 às 22:17
Muito bom Mateus! Grande dica. Vou aproveitar para deixar uma também. Na função checkAjax() não é necessário utilizar uma condição para retornar um booleano, isso porque isset() já faz isso. isset() por padrão só retorna true ou false, então é um tipo de retundância fazer como está fazendo.
Basta um ‘return isset( $var );’, que você terá o mesmo resultado de ‘return isset( $var ) ? true : false;’. http://pastebin.com/ZtNXHZGP
Grande abraço a todos!
Mateus Souza disse:
11 de novembro de 2010 às 22:28
É isso ae cara, levar conhecimento adiante…
Abraço!