views:

276

answers:

2

I wrote a script that polls Twitter via Prototype's AJAX methods, grabs JSON results, evals them and then updates a div with the formatted tweets. Everything worked fine in testing (Safari 4.0.3 on a OS 10.6.1 machine) until I loaded the script onto a server and it failed. The script had all client side items and referred to the same Prototype.js file, so I can't figure out why it was working locally but not remotely.

I stripped the script down to its bare essence -- just returning the latest tweet on my timeline into an alert box -- and works / breaks in the same way described above, and also in Firefox. I'm sure I'm making a boneheaded mistake, but can't find the error of my ways.

Here's the entirety of my page. Works locally, not on server or in Firefox:

<!DOCTYPE html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Test</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js"&gt;&lt;/script&gt;


    <script type="text/javascript" charset="utf-8">
    document.observe("dom:loaded", function(){
     var tweetAddress = "http://twitter.com/status/user_timeline/hellbox.json?count=1";
     new Ajax.Request( tweetAddress, { 
      method: 'get',
      onSuccess: function (transport) {
       var tweets = transport.responseText.evalJSON();
       alert(tweets[0].text);
      }
     });
    });
    </script> 
</head>
<body> 
</body>
</html>
A: 

Hi,

If I am not mistaken, you are trying to do an Ajax request to the twitter.com domain.

If your application itself is not hosted on that twitter.com domain, you cannot do Ajax requests to it : you can only do Ajax requests to the domain on which your application is hosted.

This means that if your website is on "www.mydomain.com", you can only send Ajax requests to "www.mydomain.com".
Not "test.mydomain.com" nor "www.anotherdomain.com"

This is because of a security restriction implemented in web-browsers, called Same Origin Policy (quoting) :

the policy permits scripts running on pages originating from the same site to access each other's methods and properties with no specific restrictions — but prevents access to most methods and properties across pages on different sites.

A possible solution to that problem might be to use a proxy on your own domain, which would proxy to twitter.com ; this way, your website could send queries to your domain, and those would actually be re-sent to twitter ; no problem with SOP, this way.


As a sidenote, When you say "it was working locally" : do you mean you have a web-server on your local machine, and it was working when served from that server ? It shouldn't have worked, in the case.

In you mean "Opening the file locally, with something like file://.../myfile.html" in the browser's address bar -- well, maybe Safari doesn't have Same Origin Policy for local documents ?
(Not sure about that -- just a possibility)

Pascal MARTIN
Thanks Pascal -- By locally I did mean opening the file directly through the local path, and it did work. However, loading it through a localhost web server stopped the file from executing.
Martin McClellan
ok, thanks for the explanation. Loading via a local web-browser, you are encountering the SOP constraint I was speaking about, which is the "expected behavior" -- you'll either have to use a proxy, or dynamically build a script tag to do that "Ajax" request for you -- you can probably search for "JSONP" about that.
Pascal MARTIN
+1  A: 

You're hitting the "same origin policy" wall. You cannot perform an AJAX request to twitter.com from a page that's loaded from another domain.

Try JSONP instead of JSON:

http://jquery-howto.blogspot.com/2009/04/twitter-jsonjsonp-api-url.html

With JSON, a <script> tag will be injected into your page and subsequently, a callback function will be called by the loaded script. There are no domain restrictions with loading scripting from external domains.

Ates Goral