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á:

Todo cabeçalho header que começar com HTTP_X é um cabeçalho personalizado.

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!!!!";
}
?>

Demonstração | Download

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

  1. 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?

    1. 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?

  2. 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!

    1. Mateus Souza disse:
      11 de novembro de 2010 às 22:28

      É isso ae cara, levar conhecimento adiante…

      Abraço!

Faça um Comentário