Search code examples
javascriptandroidcordovaxmlhttprequestsamsung-mobile

Failing XHR in PhoneGap/Cordova + Android 4.1/4.2 + Samsung Hardware


In the JavaScript below, the reqListener callback (used in the XHR call) never runs when used in a PhoneGap/Cordova app on Samsung hardware running Android 4.1 and Android 4.2. It works fine in Android 2.x and iOS. What am I doing wrong? (I hope it's something obvious. I'm OK feeling stupid about this if it means getting a fix.)

function reqListener (result) {
    var resultElement = document.getElementById('results');
    var resultText = JSON.stringify(result, null, 4);
    if ("textContent" in resultElement) {
        resultElement.textContent = resultText;
    } else {
        resultElement.innerText = resultText;
    }
};

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open('GET', 'http://apis.ucsf.edu/shuttle/stops');
oReq.send();

Full source code of an app demonstrating the issue (if you want to look at the config.xml or build it on PhoneGap Build to see it work/not work for yourself) is at https://github.com/Trott/XHRBug. It's all stock stuff except the index.html and config.xml.


Solution

  • I compared my implementation with what ZeptoJS was doing and altered it to the code below, which now works with the Galaxy S4 + PhoneGap combination that was failing before.

    I think the parts that did the trick were:

    • avoiding onload and using onreadystatechange instead
    • manually unsetting the readystatechange callback once it was fired with a readyState of 4

    And now the code:

    <title>Simple XHR Test</title>
    
    <h1>Simple XHR Test</h1>
    <p id="results">Running the simple XHR test...</p>
    
    <script>
    function reqListener (resultText) {
        var resultElement = document.getElementById('results');
        if ("textContent" in resultElement) {
            resultElement.textContent = resultText;
        } else {
            resultElement.innerText = resultText;
        }
    };
    
    var oReq = new window.XMLHttpRequest();
    oReq.onreadystatechange = function () {
        if (oReq.readyState === 4) {
            oReq.onreadystatechange = function () {};
            reqListener(oReq.responseText);
        }
    }
    oReq.open('GET', 'http://apis.ucsf.edu/shuttle/stops');
    oReq.send(null);
    </script>