Fox
Fox

Reputation: 9444

JSON data not being returned - JQuery AJAX

I am testing out this script which retrieves the weather data from the URL. But for some reason I am not getting the response back. I have enabled cross-site. Can someone point out the problem?

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
$(document).ready(function(){
  $("button").click(function(){
  $.ajax({
      type:"GET",
      url:"http://api.openweathermap.org/data/2.5/weather?q=London", 
      headers: { "Accept": "application/json; odata=verbose" },
      crossDomain:true, 
      success:function(result){
           $("#div1").html(result);
      }});
    });
});
</script>
</head>
<body>

<div id="div1"><h2>Let jQuery AJAX Change This Text</h2></div>
<button>Get External Content</button>

</body>
</html>

Upvotes: 0

Views: 3852

Answers (5)

user
user

Reputation: 4811

You need to set the dataType in the ajax call to "jsonp". Check out this jsFiddle. I found the answer (essentially) from this SO post.

$("button").click(function(){
   $.ajax({
       type:"GET",
       url:"http://api.openweathermap.org/data/2.5/weather?q=London",
       dataType : "jsonp",
       success:function(result){
           console.log(result);
            $("#div1").html(result['name']);
       },
       error: function(xhr, status, error) {
           console.log(status);
       }
     });
});

To give a little more background on why this is needed:

This is basically a way to get around browsers and cross-site protection (per my understanding--it looks like suspicious behavior to browsers). Nowadays, server owners can allow cross-site origin requests (CORS), but if the server owner (openweathermap in this case) does not, you can still request data via jsonp (see this wikipedia entry for more details: en.wikipedia.org/wiki/JSONP)

Upvotes: 1

cocco
cocco

Reputation: 16706

Soultion1

if you have php on your server create a file called weather.php width this code on the same domain as your page.

<?php
echo file_get_contents('http://api.openweathermap.org/data/2.5/weather?q='.$_GET['q']);
?>

and call it with your function

url:"weather.php?q=London",

Note: slow but real ajax

Soultion2

if openweathermap.org has support for callbacks you can use jsonp

Note: fills the page with <srcip></script> tags.

Soultion3

use a nodejs proxy

Note: fast & real ajax

Soultion4

using a yql query.

Note: fastest & real ajax

if you need more details just ask

EDIT

Solution5

A Fast way to passtrough the content with php

<?php
function w($ch,$chunk){ 
 echo $chunk;
 ob_flush();
 flush();
 return strlen($chunk);
};
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$_GET['url']);
curl_setopt($ch,CURLOPT_BINARYTRANSFER,1);
curl_setopt($ch,CURLOPT_WRITEFUNCTION,w);
curl_exec($ch);
curl_close($ch);
?>

Note: faster than file_get_contents & real ajax

by removing the

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');

part it's even faster.

EDIT3

proxy's are always a bad idea vs direct as you read the data always 2 times.

direct action

ask->read->display

proxy action

ask->(php/node ask)->(php/node read)->(php/node display)->read->display

but in your case there is no other way to get the data directly.


i tagged the yql as fastest based on average hosts.

most of the data from important sites like openweathermap is probably already cached on the yahoo servers and the their bandwith is very high worldwide (and crossorigin is allowed).

so if you have a slow host that needs to read the data from openweathermap with php or nodejs & then output having a limited bandwidth it's 99% slower than on yahoo's server.


nodejs is faster than php because if you create o good dedicated proxy script you store your data directly inside the system memory. Caching data inside the memory is faster than anything else i know.probaly it's even faster then reading a static file.

the point is how fast your host outputs the request.

Upvotes: 2

Susheel Singh
Susheel Singh

Reputation: 3854

try this you forgot to put JSONP which is used for cross domain requests:

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
    </script>
    <script>
        $(document).ready(function() {
            $("button").click(function() {
                $.ajax({
                    type: "GET",
                    dataType: "jsonp",
                    url: "http://api.openweathermap.org/data/2.5/weather?q=London",
                    crossDomain: true,
                    success: function(result) {
                        console.log(result);
                        $("#div1").html(result.clouds.all);
                    }
                });
            });
        });
    </script>
</head>
<body>
    <div id="div1"><h2>Let jQuery AJAX Change This Text</h2></div>
    <button>Get External Content</button>
</body>
</html>

Upvotes: 0

user3140081
user3140081

Reputation: 23

Your forgot dataType:"jsonp" attribute in ajax request.

Upvotes: 0

Siva Tumma
Siva Tumma

Reputation: 1701

This is the error in chrome dev console :

XMLHttpRequest cannot load http://api.openweathermap.org/data/2.5/weather?q=London. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost.com' is therefore not allowed access.

How can you say that you have enabled cross-site ? You are querying the openweathermap server, and you are not from openweathermap... Cross site enabling is not just enough setting headers in ajax. The server needs to enable its servlets (or so) to respond for ajax requests of any domain. Only then our ajax calls will be getting information from them.

Upvotes: 2

Related Questions