XHR móvel multiplataforma (PhoneGap / Cordova)

A menos que alguém esteja usando uma estrutura móvel existente ao escrever um aplicativo móvel usando PhoneGap / Cordova, quase certamente será necessário escrever um manipulador XHR para carregar vários ativos. Embora seja fácil para iOS e Android, o WP7 é outra bagunça.

Abaixo está um código que estou usando em meus projetos. Ele suporta dispositivos Android, iOS e WP7 – incluindo lidar com o fato de que o WP7 requer que os ativos sejam relativos ao diretório / app / www em vez do diretório www em outras plataformas. Isso significa que é possível carregar recursos locais em todas as três plataformas sem precisar se preocupar com as peculiaridades do WP7.

O WP7 também tem outros problemas, a saber: nenhum carregamento síncrono de conteúdo e apenas uma solicitação XHR pode ocorrer simultaneamente (pelo menos para conteúdo local) ou uma receberá conteúdo espúrio. Portanto, o código a seguir fornece uma fila para lidar com o último. Infelizmente, a única maneira de sair do primeiro é evitar o XHR síncrono em primeiro lugar.

Nota: Meu namespace aqui é PKUTIL ; sinta-se à vontade para ajustar conforme desejado. O código é licenciado pelo MIT.

/**
*

* Loads a file or URL and returns it to the completion

* handler. The completion handler must be of the form

* fn(success/failure, data).

*

*
@param theFileName the file or URL to load
*
@param aSync if TRUE, load asynchronously
*
@param completion completion block
*

*/

PKUTIL
.loadQueue = Array();
PKUTIL
.XHRinProgress = false;
PKUTIL
.XHRTimer = -1;

PKUTIL
.load = function(theFileName, aSync, completion)
{
if (device.platform != "WinCE")
{
PKUTIL
._load(theFileName, aSync, completion);
return;
}
PKUTIL
.loadQueue.push(function()
{
PKUTIL
._load(theFileName, aSync, completion);
});

if (PKUTIL.XHRTimer < 0)
{
PKUTIL
.XHRTimer = setInterval(PKUTIL._XHRQueue, 100);
}
}

PKUTIL
._XHRQueue = function()
{
if (PKUTIL.XHRinProgress)
{
return;
}
if (PKUTIL.loadQueue.length > 0)
{
var f = PKUTIL.loadQueue.pop();
f
();
}
}

PKUTIL
._load = function(theFileName, aSync, completion)
{
if (!window.XMLHttpRequest)
{
if (completion)
{
completion
(PKUTIL.COMPLETION_FAILURE, "This browser does not support XMLHttpRequest.");
return;
}
}

PKUTIL
.XHRinProgress = true;

var r = new XMLHttpRequest();
r
.onreadystatechange = function()
{
if (r.readyState == 4)// loaded
{
if (r.status == 200 || r.status == 0)// success
{
if (completion)
{
completion
(true, r.responseText);
PKUTIL
.XHRinProgress = false;
}
} else// failed to load
{
if (completion)
{
completion
(false, r.status);
PKUTIL
.XHRinProgress = false;
}
}
}
}
if (device.platform == "WinCE" && theFileName.substr(0, 4) != "http")
{
r
.open('GET', "/app/www/" + theFileName, true);
} else
{
r
.open('GET', theFileName, aSync);
}
r
.send();
}