Jesse Green
Jesse Green

Reputation: 373

Difficulty making AJAX requests in a cordova/ratchet mobile application

I was having difficulty getting my AJAX request in my cordova project to work correctly.

$.ajax({
    url: "https://mydevserver/REST.php?method=mobileGetData",
    success: function(result){
        alert("successful ajax");
    },
    error: function(xhr, ajaxOptions, thrownError){
        alert("error");
        alert("xhr.status");
        alert(thrownError);
    }
});

The status code printed in the alert with this code is 0 with an empty error message. I thought that that was odd and did some research revealing that the answer was limitations on Cross Site Scripting which could be resolved with CORS. I tried the first answer here and placed the following in my head tag.

<script src="js/jquery-2.1.1.min.js"></script>
<script>
    $(document).bind("mobileinit", function(){
        $.support.cors = true;
        $.mobile.allowCrossDomainPages = true;
    });
</script>
<script type="text/javascript" src="cordova.js"></script>

However this had no impact on the results of running the code. Further down in that same answer it is recommended to add cache: false to the ajax options as well as async: false and so I added those to my code. The result was that instead of a status code of 0 I got a status code 404 for my request. At this point I checked that I hadn't mispelled the URL somehow and tried changing the URL to example.com which also gave a status code of 404.

Next I tried that answer's third suggestion which was to use plain javascript's XMLHttpRequest object.

var req = new XMLHttpRequest();
req.open("POST", "https://mydevserver/REST.php?method=mobileGetData", true);

req.onreadystatechange = function() {
    if (req.readyState == 4) {
        if (req.status == 200) {
            alert("successful ajax");
        }else{
            alert("Error: " + req.status);
        }
    }
};
req.send(null);

This approach also yielded a status code of 0. Finally some more research revealed that the answer might be JSONP, a workaround for the Cross Site Scripting limitations built into browsers. As per his tutorial I changed my REST function and the AJAX call in my mobile app.

REST.php

if($_GET['method'] == "mobileGetData"){
    $output = array(array("Name" => "Jesse", "NumEntries" => "1")); //the end result of my actual code. I can't really put in the actual SQL queries and whatnot for security reasons
    $output = $_GET['jsonp_callback'] . "(" . json_encode($output) . ");";
    echo $output
}

AJAX

$.ajax({
    dataType: 'jsonp',
    data: 'method=mobileGetData',
    jsonp: 'jsonp_callback',
    url: "https://mydevserver/REST.php",
    success: function(result){
        alert("successful ajax");
    },
    error: function(xhr, ajaxOptions, thrownError){
        alert("error");
        alert(xhr.status);
        alert(thrownError);
    }
});

Unfortunately this attempt didn't work out either yielding a status code of 0 (although this attempt had an error message of "error" where every other attempt had a blank error message). I'm not sure what else to try or if maybe I screwed up one of the other methods I tried. Can anyone tell me where I might have gone wrong? For summary and context here's the complete head tag contents currently:

<head>
    <meta charset="utf-8" />
    <meta name="format-detection" content="telephone=no" />

    <!-- Set the viewport settings to prevent scaling -->
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, target-densitydpi=device-dpi" />

    <!-- Makes your prototype chrome-less once bookmarked to your phone's home screen -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

    <title>RealtyShout: Subscriptions</title>
    <link rel="stylesheet" type="text/css" href="css/index.css" />
    <link rel="stylesheet" href="css/ratchet.css">
    <meta name="msapplication-tap-highlight" content="no" />
    <script src="js/jquery-2.1.1.min.js"></script>
    <script>
        $(document).bind("mobileinit", function(){
            $.support.cors = true;
            $.mobile.allowCrossDomainPages = true;
        });
    </script>
    <script type="text/javascript" src="cordova.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <script src="js/ratchet.js"></script>
    <script type="text/javascript">
        app.initialize();
        $(function(){
            alert("https://mydevserver/REST.php?method=mobileGetData"));
            $.ajax({
                dataType: 'jsonp',
                data: 'method=mobileGetSubscriptionsByNotifier',
                jsonp: 'jsonp_callback',
                url: "https://mydevserver/REST.php",
                success: function(result){
                    alert("successful request");
                },
                error: function(xhr, ajaxOptions, thrownError){
                    alert("error");
                    alert(xhr.status);
                    alert(thrownError);
                }
            });
        });
    </script>
    <style>
        /*Stops the text from being in all caps*/
        body * {
            text-transform: none;    
        }
    </style>
</head>

For compiling my code I'm using the cordova CLI as follows:

cordova build ios
cordova emulate iOS

EDIT: As per @frank's suggestion I changed my URL to ip.jsontest.com to see if it was really my dev server and got back the status code 0 again. However, then I tried http://ip.jsontest.com and got status code 200 with an error code of Error: jQuery 21107076784837990999_1409318004872 was not called. My research reveals that this is caused when the server isn't configured to build JSONP responses.

Upvotes: 1

Views: 6306

Answers (2)

Jesse Green
Jesse Green

Reputation: 373

After looking here I tried using $.getJSON to make it work and managed to get a good response back.

$.getJSON("http://devserver/REST.php?callback=?", "method=mobileGetData", function(response, status, xhr){
    for(var key in response[0]){
        alert(key + ": " + response[0][key]);
    }
);

Upvotes: 0

Eduardo Romero
Eduardo Romero

Reputation: 1159

Assuming you're building your JSON/JSONP response correctly, which you could test from a web browser and the same JS code, make sure you're setting the proper headers in the response (REST.php):

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');

The Access-Control-Allow-Origin will let you request your data from outside the originating server. Which is I guess the problem you're having. Also, having the wrong response encoding might cause your Ajax call to fail.

Again, you should be able to debug your errors (if any) in the browser's console, just making the same call your app is trying to run. Double check that the response is valid.

Upvotes: 1

Related Questions