JSONRequest para evitar o Eval

{ January 4th, 2008 }


cmilfont

Autor: cmilfont

Em artigo passado, vimos a proposta de Douglas Crockford, denominado de JSON (JavaScript Object Notation) para a troca de dados. Ele propôs também uma especificação para um novo objeto como serviço nativo nos navegadores, JSONRequest, devido a ineficiência do objeto XMLHttpRequest para as novas aplicações nas próximas geração WEB (WEB 2+). Um dos pontos principais desse novo objeto é a troca segura de objetos por meio de JSON entre o lado cliente e servidor sem expô-los ao perigo.

A especificação do XHR define, por medida de segurança, que uma chamada remota só pode ser efetuada ao mesmo caminho de onde o script foi baixado, o JSONRequest resolveria esse problema habilitando o navegador a uma chamada remota a outros servidores diferentes do host original da página, possibilitando a facilidade de acesso a WEB Services REST na camada javascript.

Hoje como alternativa a esse modelo do XHR temos o Scripttag, dessa forma conseguimos acessar recursos remotos de outros servidores mas com o problema de XSS (cross site scripting). O problema principal do XSS é a injeção de código malicioso pelo parser a partir do método “Eval” para processar o código recebido. Vimos uma alternativa de contornar o problema mas mesmo assim não é suficiente. Uma das vantagens principais do JSONRequest seria evitar o XSS.

Esse objeto JSONRequest seria nativo e global, desenhado para ser simples, teria apenas 3 métodos: get, post e cancel.

Existe já plugin para o Firefox que habilita o navegador a oferecer nativamente o objeto JSONRequest.

Para todos os navegadores somente com javascript na camada mais alta, para isso existe também o projeto JSONRequest de Andrea Giammarchi, que criou o objeto em javascript seguindo a especificação. Compatível com os principais navegadores: Opera, IE, Firefox, Safari e konqueror.

try {
    JSONRequest.get("processaJSON.jsp",
        function(sn, response, exception){
             alert(exception || response);
        });
} catch(e) {
 
      alert(e);
 
}

O W3C especificou medidas seguras para acesso a recursos web em outro servidores, assim como já existem movimentos para uma nova especificação do um novo XHR, seria algo como um XHR2. A diferença no meu entendimento é que o JSONRequest trata exclusivamente da troca de objetos nativos com base em JSON entre os dois ambientes físicos, enquanto o XHR trata da troca via XML, portanto uma nova especificação do XHR não seria suficiente para substituir a proposta do JSONRequest, a não ser que ele fizesse o parser também de JSON como faz com XML.

Posted in Ajax, JSON, JavaScript, XMLHttpRequest ~ 5 Comments

Adicionar ao Rec6

O que é JSON

{ November 4th, 2007 }


cmilfont

Autor: cmilfont

A especificação do “ECMA Script” (ECMA262, 3rd Edition, December 1999), que formaliza o Javascript, define na página 2 (4.2) a sentença:

“An ECMAScript object is an unordered collection of properties each with zero or more attributes…”

Essa definição é o que chamamos de objeto literal, uma coleção não ordenada de propriedades com um ou mais elementos, onde esses elementos podem ser valores primitivos comuns a todas as linguagens como: inteiro, string ou char; ou outros objetos.

var Produto = {
	nome:"Microprocessador AMD Turion 64",
	value:150,
	custo:50,
	getValue:function(){
		return (value + custo)
	}
}

Douglas Crockford, propôs um formato de troca de dados simples com base no objeto literal do JavaScript, que denominou de JSON (JavaScript Object Notation). Esse mecanismo simples é um subconjunto do objeto literal e é facil de qualquer linguagem processar e gerar por ser baseado no formato texto, como linguagem completamente independente que usa conceitos similares às linguagens C-like. Esses motivos tornam o JSON o formato ideal de troca de dados.

JSON é construído com base em uma coleção de pares chave/valor (que definem as propriedades e seus valores), iniciado com “{” (chave aberta) e finalizado com “}” (chave fechada) . Cada chave é seguida de “:” (dois pontos) e os pares são separados por “,” (vírgula).

objeto json

var Contato = {
	"nome":"Christiano Milfont",
	"email":"cmilfont@gmail.com",
	"aniversário":"28/12/1977"
}

Um array pode ser usado como valor para uma chave, iniciado por “[" (colchete aberto) e finalizado por "]” (colchete fechado). Cada valor do array é separado por “,” (vírgula).

array json

var Contato = {
	"nome":"Christiano Milfont",
	"telefones":[
		'91942365',
		'88293759'
	]
}

Um valor pode ser uma String em aspas duplas (em javascript o valor pode ser aspa simples, é preferível que o parser resolva as duas formas, apesar de que em linguagens como java as aspas simples representam um char), ou um número, ou um booleano, ou um null, ou um outro objeto ou um array.

valores json

No caso do objeto e do array, essas estrutura podem ser aninhadas.

var Contato = {
	"nome":"Christiano Milfont",
	"endereco":{
		"rua":"Eurico Medina",
		"numero":185,
		"mapa":{
			"latitude":"",
			"longitude":""
		}
	},
	"telefones":[
		'91942365',
		'88293759'
	]
}

String é uma coleção de zero ou mais caracteres Unicode, onde a barra invertida pode ser usada para passar caracteres especais como quebra de linha, tab, entre outros. Números podem ser inteiros ou reais, menos hexadecimal ou octal.

Existem códigos de processamento JSON prontos em dezenas de linguagens, praticamente em todas as linguagens modernas voce encontra no site do projeto.

A vantagem do JSON sobre o XML como formato de troca de dados é a diminuição do tamanho da resposta, facilidade de entendimento para o programador (já que o código é similiar a linguagem que você usa), e principalmente, no caso de javascript, o parser facilitado porque é baseado em sua especificação de objeto.

Código de retorno do Flickr em XML e JSON respectivamente:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<s:Envelope xmlns:s=”http://www.w3.org/2003/05/soap-envelope”>
<s:Body>
<FlickrResponse xmlns=”http://flickr.com/ns/api#”>
<method>flickr.test.echo</method>
<format>soap2</format>
<foo>bar</foo>
<api_key>08d9221b2468be6ccfe5bc229db50181</api_key>
</FlickrResponse>
</s:Body>
</s:Envelope>

 
jsonFlickrApi({
	"method":{
		"_content":"flickr.test.echo"
	},
	"format":{
		"_content":"json"
	},
	"api_key":{
		"_content":"08d9221b2468be6ccfe5bc229db50181"
	},
	"stat":"ok"
})

Dessa forma você pode usar as estratégias de “Eval” ou “Scripttag” para processar o JSON de forma transparente em sua aplicação AJAX. Usado como configuração em aplicações no lado servidor, você pode construir uma arquitetura com base em interfaces para validar os dados, assim como validaria usando schemas no XML.

A maioria das APIs de web services dos principais Players no mercado WEB, passaram a oferecer o JSON como alternativa ao XML pela facilidade de interpretação para a arquitetura REST. Yahoo e Google são os principais expoentes desse mecanismo.

Posted in JSON, JavaScript, Web Development ~ 4 Comments

Adicionar ao Rec6

Script Tag

{ October 8th, 2007 }


cmilfont

Autor: cmilfont

Para implementar o dinamismo nas nossas páginas, usando o Javascript, precisamos trocar informações entre as camadas físicas diferentes, o cliente (por intermédio de um Browser) solicitando recursos de um servidor remoto (lado servidor).

Dentre as estratégias para essa troca de recursos entre as camadas distintas, temos IFrame, XHR e o Scripttag.

IFrame era uma técnica muito comum na era pré-ajax, mas que causava vários problemas, além da complexidade desnecessária e natureza gambiarrosa. Um dos problemas da técnica era quando se perdia a referência entre os frames e as páginas que os evocam (acontecia com uma frequência não tão insignificante). Geralmente os frameworks implementam a técnica de IFrame por questão de compatibilidade com browsers mais antigos. Quem não se lembra do escondido.jsp (ou escondido.php, escondido.asp, escondido.etc …)?

Como vimos em um post passado, a técnica de usar o XHR nos proporciona trabalhar com o parsing de XML ou a montagem dinâmica de objetos serializáveis, seja com “Eval” ou usando a capacidade dinâmica da linguagem de definir objetos de forma simples em tempo de execução. Vimos que usar Eval não é bom porque “Eval is Evil“.

A técnica de Scripttag está em alta porque aproveita a própria capacidade do browser para instanciar um trecho de código serializável entre as camadas físicas distintas. A técnica está descrita no Pattern Lazy Loading Javascript ou On-Demand javascript

A técnica consiste em se obter um recurso do servidor em forma de texto, mas já formatado como um código (entidade) javascript e adicionar esse trecho na seção head da página, fazendo com que o próprio Browser instancie como se estivesse lendo a página na carga inicial. Vejamos:

function JSONRequest(url) {
   var head = document.getElementsByTagName("head")[0];
   var script = document.createElement('script');
   script.id = 'TriadworksOnDemand';
   script.type = 'text/javascript';
   script.src = url;
   head.appendChild(script)
}
 
function montaGrid(usuarios) {
    //aguarda um array de usuarios
    for(var x in usuarios) {
        //pega usuarios[x]...
    }
}
 
function pesquisar(id) {
    var url = 'http://server_path/usuario/'+id
                 +"/?callback="+montaGrid;
    JSONRequest(url);
}
 
pesquisar(101);

Observe que criamos uma função chamada JSONRequest, que basicamente pega uma url e adiciona dinamicamente na seção head da página. Essa url é uma saída texto pelo servidor no formato JSON, utilizando o modelo REST para obter um recurso, ou seja, o servidor responde com um objeto serializável no endereço /usuario/id porque ele reconhece que as requisições a esse endereço são lógicas CRUD para a captura do recurso “usuário”. Passo como parâmetro uma variável chamada callback para o servidor renderizar a execução dessa função para ser interpretada assim que o Browser anexar a resposta.

A resposta viria mais ou menos assim:

montaGrid( [
          {'id':'101',
           'nome':'Christiano',
           'sobrenome':'Milfont',
           'email':'cmilfont@gmail.com'
          } ] )

AO executar a função JSONRequest, o código anexa a resposta do servidor na seção Head da página e então o Browser interpreta como se estivesse lendo na carga da página, executando a função montaGrid.

Diferenças entre as abordagens Scripttag e XHR.

XmlHttpRequest Dynamic script Tag
Compatível com Cross-browser? Não * Sim
Cross-domain browser security enforced? Sim Não
Trabalha com HTTP status codes? Sim Não (falha com outro código HTTP diferente de 200)
Supports HTTP GET and POST? Sim Não (Somente GET)
Pode receber/enviar HTTP headers? Sim Não
Pode receber XML? Sim Sim (mas embutido na sentença JavaScript)
Pode receber JSON? Sim Sim (mas embutido na sentença JavaScript)
Oferece chamadas síncronas e assíncronas? Sim Não (somente assíncronas)

* - Basicamente poderíamos dizer que é compatível sim, mas com a diferença na implementação. Somente os browsers mais antigos não possuirão o objeto necessário.

Então o uso racional das abordagens vai depender da necessidade de características de cada uma, cada qual possui suas vantagens e desvantagens. Mais em XML.com.

Posted in Ajax, JSON, JavaScript, Web Development, XMLHttpRequest ~ 7 Comments

Adicionar ao Rec6