jQuery - Requesting data from webservice

Hi

I am trying to get values from a third party webservice. When I resolve the API link directly in my browser, it works fine and shows result (in json format)


API Link: http://outlineme.com/test/index.php

Result: {"result":true,"time":"2013-04-28 08:19:10"}

But when I run the same code using jQuery AJAX (with JSONP datatype) it does not show up anything. My code is below:


$(document).ready(function(){

    $.ajax({
      url: 'http://outlineme.com/test/index.php',
      data: "",
      type: 'get',
        dataType: 'jsonp'  ,
      success:function(result){

        alert(result.time);
    }});





});

JS Fiddle: http://jsfiddle.net/WgZ9c/1/

Can someone pls tell me what am I missing here?

Many thanks

Hi,

The problem here seems to be that the server is responding with JSON and not JSONP.

i.e. you are getting:

{"result":true,"time":"2013-04-28 09:24:55"}

But jQuery is expecting:

jQuery191043281922047026455_1367141020954({"result":true,"time":"2013-04-28 09:24:55"})

Is there some kind of documentation for the outlineme.com API?

No, its just a test script. So is there any thing we need to do in the outlineme.com api in order to make the request a success?

Oh, ok.
Do you have access to /test/index.php on the outlineme server?

Yes,

this is the content of the script

<?php

$a = array(‘result’ => true, ‘time’ => date(‘Y-m-d H:i:s’));

echo json_encode($a);
die;

Hoiwdy,

Change /test/index.php to this:

<?php
$data = json_encode(array('result' => true, 'time' => date('Y-m-d H:i:s')));
echo $_GET['callback'] . '(' . $data . ');';
?>

Then change your AJAX call to this:

$(document).ready(function(){
  $.ajax({
    dataType: 'jsonp',
    url: 'http://outlineme.com/test/index.php',
    success: function (result) {
      console.log(result.time);
    }
  });
})

;

Does that work?

Yes, it works like a charm.

So 3 questions now:

  1. Why was it necessary to do that change?

  2. What changes (both in server and client side) do we have to do if its an XML datatype instead of json?

  3. Is there no way we can use json instead of jsonp?

It’s a cross domain thing. The following is from Stack Overflow

Say you’re on domain abc.com, and you want to make a request to domain xyz.com. To do so, you need to cross domain boundaries, a no-no in most of browserland.

The one item that bypasses this limitation is <script> tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can’t really DO anything with the results, the script just gets evaluated.

Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.

For example, say the server expects a parameter called “callback” to enable its JSONP capabilities. Then your request would look like:

http://www.xyz.com/sample.aspx?callback=mycallback

Without JSONP, this might return some basic javascript object, like so:

{ foo: 'bar' }

However, with JSONP, when the server receives the “callback” parameter, it wraps up the result a little differently, returning something like this:

mycallback({ foo: 'bar' });

As you can see, it will now invoke the method you specified. So, in your page, you define the callback function:

mycallback = function(data){
  alert(data.foo);
};

And now, when the script is loaded, it’ll be evaluated, and your function will be executed. Voila, cross-domain requests!

Source: http://stackoverflow.com/questions/2067472/what-is-jsonp-all-about

Not really, sure. Sorry.
Try asking here: http://www.sitepoint.com/forums/forumdisplay.php?215-XML-amp-Web-Services

Not if you want the API to be accessible from domains outside of onlineme.com

HTH

I see. Thanks for the explanation.

  1. But with php instead of jquery, u do not have to do anything special. Why so?

  2. Can we also make this work using Normal JS Ajax? See example: http://jsfiddle.net/cXLd7/

  3. Why did u add $_GET[‘callback’] in the php script? I see no usage of it in the jQuery script anyway?

Note: I have updated your script in new page: http://outlineme.com/test/index2.php

No problem :slight_smile:

I’m not sure I understand what you mean here.

Sure. Anything jQuery can do JavaScript can do, too (since jQuery is JavaScript)

Your original AJAX request looks something like this:

http://outlineme.com/test/index2.php?callback=jQuery19109609727570787072_1367149390885&_=1367149390886

The PHP script retrieves the 'callback' parameter from the $_GET superglobal array, then uses that to construct its answer.

This would look something like this:

jQuery19108379775104112923_1367149616043({"result":true,"time":"2013-04-28 11:46:48"});

This is evaluated by your success callback in which the following JSON object is then available:

{"result":true,"time":"2013-04-28 11:46:48"}

I mean, when getting the same request with PHP, there is no concept of JSONP, all you can do is run a CURL request to the API server and store the output in a variable say $response and then json decode the response:

$res_decode = json_decode($response);
echo $res_decode->time;

I was unable to get this to work even after passing the “callback” param: http://jsfiddle.net/cXLd7/1/

Pls help me modify the script and make it work.

Is it really important to have $_GET[‘callback’] in the API script?

Thanks

Yeah, as I mentioned, cross-domain requests in JS ar a no-no. cURL is a different ball game and AFAIK isn’t subject to the same restrictions.
It’s like comparing apples and pears.

As script tags bypass the cross-domain limitation, I would just dynamically create one of these and embed it in your page, then run a call-back function to do whatever it is you need with the JSON.
Here’s an updated fiddle

AFAIK, yes.
In my above example, try swapping out:

http://outlineme.com/test/index2.php?callback=displayTime

with your previous version (without $_GET['callback']).

http://outlineme.com/test/index.php

As you’ll see, it doesn’t work.

HTH

If it helps, JSONP is just JSON with padding. That’s why it’s called JSONP.

Here’s a rundown of what JSON is, and how JSONP helps to solve certain problems.

Some JSON code is:


{"Name": "Foo", "Id": 1234, "Rank": 7}

But if you try to retrieve that JSON code from a different web server, you will face cross-domain issues.

It’s possible though to obtain that content from a script tag because script tags are allowed to access content from other domains.


<script src="http://otherdomain.com/user/1234"></script>

However, JSON data is not valid scripting code. That script tag will throw a syntax error when it tries to execute the retrieved JSON data.

So, the solution is to have that other domain pad that JSON data with a function call. That is the entire purpose of what JSONP is.


<script src="http://otherdomain.com/user/1234?jsonp=parseResponse"></script>

Which, if the server is setup to handle JSONP requests, will result in the following padded JSON data (padded by that function call) from the server.


parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});

The JSON code is now padded with the name of the function that you provided.

This now allows you to make the cross-domain call for data, and pass that data to a function of your choice to handle things.

Hi

Can this be achieved using core javascript and without using the SCRIPT tag?

Thanks

No.

ok thanks for confirming that.

So if the API supports both JSON and JSONP, will it be wrong to say that the API supports 2 formats? Or is it counted as just 1 format?

Thanks

Yes, it can be said to support two formats. They both use JSON data, but JSONP is wrapped with the name of a function of your choosing.