0

I am trying to build a mobile app with JQuery Mobile and PhoneGap. This app will hit a backend I'm working on with ASP.NET MVC 3. Right now, I'm just trying to get a basic GET/POST to work. I've created the following test page.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">

    <link rel="stylesheet" href="resources/css/themes/default/core.css" />    
    <link rel="stylesheet" href="resources/css/themes/default/app.css" />

    <script src="resources/scripts/jquery-1.6.4.min.js" type="text/javascript"></script> 
    <script src="resources/scripts/jquery.mobile-1.1.0.min.js" type="text/javascript"></script>

    <script type="text/javascript">
      function initialize() {
      $.support.cors = true;
          $.mobile.allowCrossDomainPages = true;
      }
    </script>
  </head>

  <body onload="initialize();">
    <div id="testPage" data-role="page">
    <div data-role="header" data-position="fixed">
      <h1>TEST</h1>
    </div>

    <div data-role="content">
      <input id="twitterButton" type="button" value="Test GET via Twitter" onclick="twitterButton_Click();" />
      <input id="getButton" type="button" value="Test GET via MVC 3" onclick="getButton_Click();" />
      <input id="postButton" type="button" value="Test POST via MVC 3" onclick="postButton_Click();" />

      <div id="status"></div>
    </div>

    <div data-role="footer" class="ui-bar" data-position="fixed"> 

    </div>

    <script type="text/javascript">
      function twitterButton_Click() {
        $("#status").html("Testing Twitter...");
          var vm = { q:"1" };
          $.ajax({
      url: "http://search.twitter.com/search.json?q=weekend&rpp=5&include_entities=true&result_type=mixed",
            type: "GET",
            dataType: "jsonp",
            contentType: "application/json",
            success: twitter_Succeeded,
            error: twitter_Failed
          });
        }

        function twitter_Succeeded(result) {
          $("#status").html("Twitter GET Succeeded!");
        }

        function twitter_Failed(p1, p2, p3) {
          $("#status").html("Twitter GET Failed :(");
        }

        function getButton_Click() {
          $("#status").html("Testing Get...");

          var vm = { q:"1" };
          $.ajax({
            url: "https://www.mydomain.com/myService/testGet",
            type: "GET",
            data: vm,
            contentType: "application/json",
            success: get_Succeeded,
            error: get_Failed
          });
        }

        function get_Succeeded(result) {
            $("#status").html("MVC 3 GET Succeeded!");
        }

        function get_Failed(p1, p2, p3) {
            $("#status").html("MVC 3 GET Failed :(");
        }

        function postButton_Click() {
          $("#status").html("Testing POST...");

          var vm = { data:"some test data" };
          $.ajax({
            url: "https://www.mydomain.com/myService/testPost",
            type: "POST",
            data: JSON.stringify(vm),
            contentType: "application/json",
            success: post_Succeeded,
            error: post_Failed
          });       
        }

        function post_Succeeded(result) {
            $("#status").html("MVC 3 POST Succeeded!");
        }

        function post_Failed(p1, p2, p3) {
            $("#status").html("MVC 3 POST Failed :(");
        }
    </script>
</div>
</body>
</html>

When I run this page from within Visual Studio, I change the AJAX url calls to be relative calls. They work perfectly. However, because my goal is run this app from within PhoneGap, I know that this page will actually run as a local file (http://jquerymobile.com/demos/1.1.0/docs/pages/phonegap.html). Because of this, I've used the code above and created test.html on my local machine.

When I try to run this code, the Twitter test works. Oddly, all three actions work in Internet Explorer. However, when I use Chrome or FireFox, the tests to my server do NOT work. In Chrome, I notice the following in the console:

XMLHttpRequest cannot load https://www.mydomain.com/myService/testGet?q=1. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load https://www.mydomain.com/myService/testPost. Origin null is not allowed by Access-Control-Allow-Origin.

I reviewed this: Ways to circumvent the same-origin policy. However, none of them seem to work. I feel like there is some server side configuration I'm missing. Currently, my TestGet and TestPost actions look like the following:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult TestGet(string q)
{
  Response.AppendHeader("Access-Control-Allow-Origin", "*");
  return Json(new { original = q, response=DateTime.UtcNow.Millisecond }, JsonRequestBehavior.AllowGet);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TestPost(string data)
{
  Response.AppendHeader("Access-Control-Allow-Origin", "*");
  return Json(new { status=1, response = DateTime.UtcNow.Millisecond }, JsonRequestBehavior.AllowGet);
}

I feel like I'm SO close to getting this work. What am I missing? Anyhelp is sincerely appreciated.

Community
  • 1
  • 1
user70192
  • 13,786
  • 51
  • 160
  • 240

1 Answers1

0

Try it from an actual device or simulator and it will work. From the FAQ:

The cross-domain security policy does not affect PhoneGap applications. Since the html files are called by webkit with the file:// protocol, the security policy does not apply. (in Android,you may grant android.permission.INTERNET to your app by edit the AndroidManifest.xml)

It will always work with Twitter as it uses JSONP to respond to queries. You have to start Chrome or Firefox the proper way to tell it to allow CORS. For Chrome it is:

chrome --disable-web-security
Simon MacDonald
  • 23,253
  • 5
  • 58
  • 74