tags:

views:

101

answers:

2

Hello,

I am using jquery to build a request to the Twitter Search API. I am using jsonp, as is needed for cross-domain requests. However, the Twitter API specifies that you should set a unique User-Agent for these requests, and limits your requests if you do not. The problem is, I see no way of setting this header via jquery.

This is the code I am using:

$.ajax({
    url: 'http://search.twitter.com/search.json',
    dataType: 'jsonp',
    type: 'get',
    data: { q: 'twitter' },
    success: function(data) {
        alert(data.results);
    }
});

I have tried using the beforeSend method, but it appears that this event is not firing. Can anyone come up with any way of solving this problem?

Thanks.

+4  A: 

JSON with Padding works by adding a script element to the page, with the src attribute pointing to the URL of the web service. The web service then returns a script containing the data wrapped in a callback function that is executed when the script finishes parsing. It's not so much JSON (it doesn't even have to be valid JSON, for a start) as it is Plain JavaScript.

There's no way to modify the headers sent for a script element that's added to your page unfortunately. The only thing you can do is check for a cross-origin compatible method of retrieving data, such as:

  • XMLHttpRequest Level 2 - Safari 4+, Firefox 3.5+

    // Is XMLHttpRequest Level 2 supported?
    if ("withCredentials" in new XMLHttpRequest()) 
  • XDomainRequest - for IE8

    // Is XDomainRequest supported?
    if ("XDomainRequest" in window)

It would be a good idea to test for these implementations if they exist and use them accordingly, falling back to standard JSONP for unsupported or older browsers.

It's also possible (but unlikely, given that it's high profile) that the web service isn't set up to allow cross-origin requests, so you may still have to fall back to JSONP if the request fails. See also, Cross-Origin Resource Sharing.

Andy E
+1 nice detailed answer with useful info :)
Sarfraz
Ah, that is incredibly unfortunate. I think I will fall back on using a wrapper script written in PHP that goes out and gets the data. That way, I can cache the search, so maybe it's a win-win (though it means more work).Thanks for the detailed answer.
Dan D.
A: 

You can do this theoretically by getting at the XMLHttpRequest object before it gets sent:

Your example would then become:

$.ajax({
    url: 'http://search.twitter.com/search.json',
    dataType: 'jsonp',
    type: 'get',
    data: { q: 'twitter' },

    // Notice this addition:
    beforeSend: function(httpr) {
        httpr.setRequestHeader('User-Agent', 'whatever');
    },

    success: function(data) {
        alert(data.results);
    }
});

See what's happening here? Before the request is sent, you are setting the User-Agent header.

Now for the warning... not all browsers allow this to be changed, so you may be out of luck.

George Edison
If it were an *XMLHttpRequest* object making the call it would be blocked by the same-origin policy. JSONP works by adding a script element to the page, so there is no *XMLHttpRequest*.
Andy E
@Andy E: *[slaps forehead]* Oh yeah.... I think I'll keep the answer though in case someone wants to know how to do it with plain JSON.
George Edison