Ajax Crossbrowser no IE8 e FF3

{ March 9th, 2008 }


cmilfont

Autor: cmilfont

Uma confusão muito comum até em desenvolvedores profissionais é não saber que o objeto XHR segue o mesmo princípio de segurança do javascript e por isso não pode executar uma chamada remota a outro endereço que não o mesmo de onde o arquivo é chamado. Isso é chamado de “Same Domain Policy“.

A alternativa para contornar esse problema é usar a estratégia de Scripttag quando o recurso externo permite ou usar um script como proxy no servidor para buscar o recurso e devolver via Ajax. Existem outras formas mais porcas de fazer isso que nem merecem consideração.

O Firefox 3 vem com o recurso de XHR Crossbrowser, agora seguido do IE8. Sinceramente isso não muda nada a curto prazo, até termos as versões anteriores do FF e principalmente do IE aposentadas, teremos que contornar isso com as gambiarras de sempre.

O John Resig (Criador do JQuery) mostra nesse post como usar isso no FF3. Lembrando que isso só funciona no FF3 que ainda é beta.

Posted in Ajax, JavaScript, Web Development, XMLHttpRequest ~ 8 Comments

Adicionar ao Rec6

Currying em Javascript

{ March 2nd, 2008 }


cmilfont

Autor: cmilfont

Uma característica de linguagens funcionais muito usada em Javascript é a técnica de Currying, a grosso modo de explicar, usada para transformar uma função com n argumentos em uma outra função com argumentos simples.

1
2
3
4
5
6
7
8
9
 function pow(i, j) { 
     return i * j;
 }
 
 function square (k) {
     return pow(k, 2);
 }
 
 alert(square(6));

Veja nesse exemplo que uma função denominada de pow (que multiplica dois elementos) é usada na função square (que multiplica sempre um elemento por 2) de forma que você tem o uso de primeira pela segunda com uma redução de parâmetros. Essa técnica é usada nas funções de alta ordem como Fold, Map, etc.

1
2
3
4
5
6
7
8
Array.prototype.each = function(fn){
	for(var i = 0, len = this.length; i<len; ++i ) {
		fn.call(this,this[i]);
	}
}
var multiplicar = function(i) { alert(i * 2); }
var teste = [1,2,3];
teste.each(multiplicar);

Exemplo acima usando uma função que aplica outra função para cada elemento de um array.
Essa técnica ficou popular mesmo sendo usada junto a Closure que precisam de funções de callback para processar um resultado de outra função.

Explicando isso em código, teríamos Currying da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
 function atualizar(id) {
     return function(resposta) {
          document.getElementById(id).innerHTML = resposta;
     };
 }
 
 function processar(msg, fn) {
     fn(msg);
 };
 
processar('testando currying em ação', atualizar('area'));

Na linha 1, temos a declaração de uma função denominada atualizar que recebe um parâmetro em seu construtor que será o id de um elemento qualquer. A chamada a essa função provoca o retorno de uma outra função declarada internamente na linha 3. Essa função interna recebe também um argumento e a função dela é adicionar esse argumento no conteúdo do elemento passado como parâmetro na função inicial. Criei uma função chamada processar apenas para aplicar uma mensagem a um função, será usada para fazer a mágica do Currying aqui. Veja na linha 15 que usei a função processar para submeter uma frase (primeiro argumento) na função atualizar (segundo argumento), passando para ela o id de um elemento como um DIV.

Observe que esse código é muito comum em frameworks ajax, um exemplo claro disso seria como o DWR trabalha.

1
2
3
4
5
 function callback(retorno) {
     alert(retorno);
 }
 
DWRInterface.metodo(callback);

Aqui aplicamos a função callback na função “metodo” que é um método do objeto DWRInterface controlado pelo framework DWR. DEssa forma quando o DWR processar a requisição ajax, submete o retorno vindo do servidor para a função callback que o recebe como parâmetro.
Vamos investigar outras características de linguagens funcionais nos próximos artigos.

Posted in JavaScript, Programação funcional, Web Development ~ 6 Comments

Adicionar ao Rec6

Datas e Fuso horário no Javascript

{ February 24th, 2008 }


cmilfont

Autor: cmilfont

As operações com datas no javascript sofrem da variação de fuso horário no qual a máquina cliente está configurada.

Certa oportunidade tive que consertar uma função que apresentava diferença entre datas e ninguém sabia o porque. Quando você instancia uma data, o retorno dela aparecerá assim:”Thu Feb 14 2008 08:41:27 GMT-0300 (Hora oficial do Brasil)”.

Observe que na data consta o GMT (Greenwich Mean Time) que indica em que fuso horário a data está configurada.

Vou demonstrar como evitar a diferença de tempo provocada por isso em operações com data. Para isso basta criar uma função que converta a data sempre para o fuso que se espera.

1
2
3
4
5
6
7
8
9
 var calcularFuso = function(data, offset) {
 
    var utc = data.getTime() + (data.getTimezoneOffset() * 60000);
 
    var nd = new Date(utc + (3600000*offset));
 
    return nd;
 
 }

Observe que na linha 3, invocamos o método getTime() que converte o momento local da data para um número representado pelos milisegundos desde 1º de Janeiro de 1970 (Unix Epoch). Obtemos o atual fuso horário que está configurado no browser pelo método getTimezoneOffset() da API de data no javascript e multiplicamos pelos milisegundos de tempo de uma hora. Somamos então os dois valores.

Porque uma hora? Porque esse é o tempo que representa cada fuso horário. Por default esse método retorna esse fuso horário em minutos, por isso a conversão em hora é necessária.

Para chegar nesse número 60000 você tem que lembrar que 1 segundo tem 1000 milisegundos e que 1 minuto tem 60 segundos, então convertendo minutos para milisegundos multiplicamos 60 * 1000 = 60000.

Nesse momento temos o UTC (Coordinated Universal Time) representado pela variável “utc” pela soma do momento local mais o fuso horário local em milisegundos.

Precisamos agora obter uma data a partir desse UTC somado com o fuso horário de destino, como por exemplo uma data expressa no fuso +5 transformado no fuso do Brasil (hora de Brasília) -3.

Observe que na linha 5 que obtemos um offset (representação do fuso) em hora e convertemos para milisegundos. Lembre-se aqui que 1 segundo tem 1000 milisegundos e que 1 hora tem 3600 segundos, portanto converter hora em milisegundo deve-se multiplicar 1000 * 3600 = 3600000.

Somamos esse resultado com o valor da variável “utc” e obtemos o momento para o fuso horável desejado, a partir daí criamos uma nova data com base no long apropriado e retornamos essa nova data.

Dessa forma conseguimos manter a integridade desejada na aplicação quando precisamos expressar a data no fuso horário correto.

Posted in JavaScript, Web Development ~ 4 Comments

Adicionar ao Rec6