1

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.

Community
  • 1
  • 1
Jesse Green
  • 373
  • 2
  • 6
  • 20
  • How are you testing your cordova APP? Are you testing using the emulator or actual device?. The issue might be related to network settings. Your `https://mydevserver` might not be visible to the App with respect to the testing method you are using. Can you open a **Mobile** browser in the actual device/emulator and make a request `https://mydevserver/REST.php?method=mobileGetData`? Does it return any data? – frank Aug 28 '14 at 18:40
  • I'm using `cordova emulate ios` which I think uses a utility called `ios-sim` although I'm not entirely positive on that one. If I go to the browser in the virtual iPhone I can get a good response from REST.php without any problems. – Jesse Green Aug 28 '14 at 18:51
  • Can you check that '' is set to `*` in the config.xml file. Also I have noticed that you are using `https` a secure connection. Have you tried it with `http` only?. Over [here](http://stackoverflow.com/questions/20036260/phonegap-android-app-ajax-requests-to-https-fail-with-status-0) folks have discussed issues with `https` – frank Aug 28 '14 at 20:33
  • The tag in config.xml is correct. If I switch to http then the same thing happens it just takes a minute or so for the error message to get printed. I think it's because our server is configured to timeout requests that don't come securely for security reasons. Having looked at the link you gave @frank I'm pretty sure the issue is that our cert isn't correct for the dev server. I'll have to check with our admin on that to know for sure though. – Jesse Green Aug 28 '14 at 21:00
  • You could try a public JSON api for testing your code. That would confirm that the issue is with your DEV server and not your code. Here is a [link](http://www.jsontest.com/) to a public JSON service. – frank Aug 29 '14 at 07:05
  • @frank still get a status code 0 from jsontest. – Jesse Green Aug 29 '14 at 13:10
  • Added some more information to OP, http://ip.jsontest.com returns a code of 200 with an error message. – Jesse Green Aug 29 '14 at 13:15
  • Have you specified `dataType: 'json'`. What is the error message? Note that inside the error event, parameter 2 and 3 will contain details about the error. – frank Aug 29 '14 at 13:36
  • @frank, are you referring to the thrownError parameter in the error function? attempting to print indices of thrownError yields `undefined` – Jesse Green Aug 29 '14 at 14:08
  • `error: function(xhr, status, thrownError) {console.log(xhr.responseText)}`. also I think thrownError is of type String. You can directly print it. Can you print the last two. e.g `console.log(status)` and `console.log(thrownError)`; – frank Aug 29 '14 at 14:26
  • `console.log(status)` yields `'error'` and `console.log(xhr.responseText)` yields `undefined`. – Jesse Green Aug 29 '14 at 14:35

2 Answers2

1

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.

Eduardo Romero
  • 1,159
  • 8
  • 10
  • Adding the two header lines to my REST.php script failed to change the output. I tried just running the page with the AJAX call in it in my browser and it works just fine. – Jesse Green Aug 28 '14 at 19:38
0

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]);
    }
);
Community
  • 1
  • 1
Jesse Green
  • 373
  • 2
  • 6
  • 20