views:

5730

answers:

5

Hey everyone, I'm working on a widget for Apple's Dashboard and I've run into a problem while trying to get data from my server using jquery's ajax function. Here's my javascript code:

$.getJSON("http://example.com/getData.php?act=data",function(json) { 
    $("#devMessage").html(json.message)
    if(json.version != version) {
        $("#latestVersion").css("color","red")
    }
    $("#latestVersion").html(json.version)
})

And the server responds with this json:

{"message":"Hello World","version":"1.0"}

For some reason though, when I run this the fields on the widget don't change. From debugging, I've learned that the widget doesn't even make the request to the server, so it makes me think that Apple has some kind of external URL block in place. I know this can't be true though, because many widgets phone home to check for updates.

Does anyone have any ideas as to what could be wrong?

EDIT: Also, this code works perfectly fine in Safari.


As requested by Luca, here's the PHP and Javascript code that's running right now:

PHP:

echo $_GET["callback"].'({"message":"Hello World","version":"1.0"});';

Javascript:

function showBack(event)
{
var front = document.getElementById("front");
var back = document.getElementById("back");

if (window.widget) {
    widget.prepareForTransition("ToBack");
}

front.style.display = "none";
back.style.display = "block";
stopTime();
if (window.widget) {
    setTimeout('widget.performTransition();', 0);
}
$.getJSON('http://nakedsteve.com/data/the-button.php?callback=?',function(json) { 
 $("#devMessage").html(json.message)
    if(json.version != version) {
        $("#latestVersion").css("color","red")
    }
    $("#latestVersion").html(json.version)
})
}
A: 

Interesting that it works in Safari. As far as I know to do x-domain ajax requests you need to use the jsonp dataType.

http://docs.jquery.com/Ajax/jQuery.getJSON

http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/

Basically you need to add callback=? to your query string and jquery will automatically replace it with the correct method eg:

$.getJSON("http://example.com/getData.php?act=data&callback=?",function(){ ... });

EDIT: put the callback=? bit at the end of the query string just to be safe.

sanchothefat
+3  A: 

Cross-domain Ajax requests ( Using the XMLHttpRequest / ActiveX object ) are not allowed in the current standard, as per the W3C spec:

This specification does not include the following features which are being considered for a future version of this specification:

  • Cross-site XMLHttpRequest;

However there's 1 technique of doing ajax requests cross-domain, JSONP, by including a script tag on the page, and with a little server configuration.

jQuery supports this, but instead of responding on your server with this

{"message":"Hello World","version":"1.0"}

you'll want to respond with this:

myCallback({"message":"Hello World","version":"1.0"});

myCallback must be the value in the "callback" parameter you passed in the $.getJSON() function. So if I was using PHP, this would work:

echo $_GET["callback"].'({"message":"Hello World","version":"1.0"});';
Luca Matteis
I tried adding ?callback=? to the end of the url, and I used that exact PHP code on the server and still nothing.
Vestonian
Can we see the Javascript and the PHP code? Also is the Javascript console outputting any errors?
Luca Matteis
There you go, and no, dashcode isn't reporting anything in the runlog.
Vestonian
A Dashboard widget is essentially a web page -- making a request to a server somewhere. No domain crossings, even if the OQ (original questioner) puts it in the question.
slothbear
A: 

If you are creating a dashboard widget, why don't you use the XMLHttpRequest Setup function in the code library of DashCode. Apple built these in so you don't need to install 3rd party JS libraries. I'm not sure about JSON support but perhaps starting here will lead you in a better direction.

Paulo
Because jQuery's ajax functions use 1 line of code, so it looks better.
Vestonian
+2  A: 

Apple has some kind of external URL block in place.

In your Info.plist you need to have the key AllowNetworkAccess set to true.

<key>allowNetworkAccess</key>
<true/>

Your code works in Safari because it is not constrained in the dashboard sever and it is not standards complient in that it DOES allow cross site AJAX. FF IS standards complient in that it DOES NOT allow cross site ajax.

Hyposaurus
+5  A: 

In Dashcode click Widget Attributes then Allow Network Access make sure that option is checked. I've built something that simply refused to work, and this was the solution.

Tom
A bit late of a response, but that did it!
Vestonian