【问题标题】:JSON data not being returned - JQuery AJAX未返回 JSON 数据 - JQuery AJAX
【发布时间】:2013-12-27 17:58:25
【问题描述】:

我正在测试这个从 URL 检索天气数据的脚本。但由于某种原因,我没有得到回复。我启用了跨站点。有人可以指出问题吗?

<!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>

【问题讨论】:

  • 否,openweathermap.org 上未启用跨域来源
  • 我怎样才能找到它?
  • chrome->inspect element->Network->Headers->Response-header.. 你看到一个字符串 Access-Control-Allow-Origin:*
  • 更正 - 打开的天气图现在支持 CORS。

标签: javascript jquery ajax json


【解决方案1】:

这是 chrome 开发控制台中的错误:

XMLHttpRequest 无法加载 http://api.openweathermap.org/data/2.5/weather?q=London。 请求的资源上不存在“Access-Control-Allow-Origin”标头。 因此,Origin 'http://localhost.com' 不允许访问。

你怎么能说你启用了跨站?您正在查询 openweathermap 服务器,但您不是来自 openweathermap... 跨站点启用不仅仅是在 ajax 中设置标题就足够了。服务器需要启用其 servlet(或其他)来响应任何域的 ajax 请求。只有这样我们的 ajax 调用才会从它们那里获取信息。

【讨论】:

  • “跨站点启用不仅仅是在 ajax 中设置标头就足够了” - 实际上服务器所做的是完全发送允许它的 HTTP 标头:)
【解决方案2】:

灵魂1

如果您的服务器上有 php,请在与您的页面相同的域中创建一个名为 weather.php 的文件。

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

并用你的函数调用它

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

注意:缓慢但真实的 ajax

Soultion2

如果 openweathermap.org 支持回调,您可以使用 jsonp

注意:&lt;srcip&gt;&lt;/script&gt;标签填充页面。

Soultion3

使用 nodejs 代理

注意:快速且真实的 ajax

Soultion4

使用 yql 查询。

注意:最快且真正的 ajax

如果您需要更多详细信息,请询问

编辑

解决方案5

使用 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);
?>

注意:比 file_get_contents 和真正的 ajax 更快

通过删除

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

它甚至更快。

EDIT3

代理与直接相比总是一个坏主意,因为您总是读取数据 2 次。

直接行动

询问->阅读->显示

代理操作

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

但在您的情况下,没有其他方法可以直接获取数据。


根据平均主机,我将 yql 标记为最快。

来自 openweathermap 等重要站点的大部分数据可能已经缓存在 yahoo 服务器上,并且它们的带宽在全球范围内非常高(并且允许跨域)。

因此,如果您的主机速度较慢,需要使用 php 或 nodejs 从 openweathermap 读取数据,然后输出带宽有限,则它比 yahoo 的服务器慢 99%。


nodejs 比 php 更快,因为如果您创建一个好的专用代理脚本,您可以将数据直接存储在系统内存中。在内存中缓存数据比我知道的任何其他东西都要快。可能比读取静态文件还要快。

关键是您的主机输出请求的速度。

【讨论】:

  • 我不认为 php 代理自动比 NodeJS 慢得多。你的案例很好,但为什么一个比另一个好?你会做什么?为什么?
  • php 要慢得多...根据我前段时间所做的测试,如果您不在一个好的主机上,因为您需要阅读内容 2 次。 nodejs 更快地处理这种类型的通信。 yql 查询在雅虎服务器上,一些数据已经被缓存。 jquery 是呸..
  • 同一个 cpu 服务器处理 nodejs 脚本的内容比 php 快得多。我还写了一个不错的 curl 示例,女巫相对较快,它使用写入功能读取内容并刷新数据.. 但对于这样的简短回答,它是不必要的。
  • 看,我真的不想争论你的基准是什么,你应该将 Node 的 http 库客户端与 Atrax 之类的东西进行比较,当然不应该与 file_get_contents 进行比较。 .. PHP 中存在 a 缓慢阻塞 HTTP 客户端这一事实绝不意味着没有快速阻塞客户端。请不要传播 FUD,完全有可能用 PHP、Python、JavaScript 和 node 或几乎任何其他语言编写这种“代理”......请考虑编辑您的答案以详细说明案例及其优势/缺点。
  • 另外 - 这里的问题真的不是代理速度 - 这就是为什么代理是一个好/坏的主意。每种方法有什么优势等等。
【解决方案3】:

您需要将 ajax 调用中的 dataType 设置为“jsonp”。看看这个jsFiddle。我从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);
       }
     });
});

提供更多关于为什么需要这样做的背景:

这基本上是一种绕过浏览器和跨站点保护的方法(根据我的理解——它看起来像是浏览器的可疑行为)。如今,服务器所有者可以允许跨站点源请求 (CORS),但如果服务器所有者(本例中为 openweathermap)不允许,您仍然可以通过 jsonp 请求数据(有关更多详细信息,请参阅此维基百科条目:en.wikipedia.org /wiki/JSONP)

【讨论】:

  • 这基本上是一种绕过浏览器和跨站点保护的方法(根据我的理解——它看起来像是浏览器的可疑行为)。如今,服务器所有者可以允许跨站点源请求 (CORS),但如果服务器所有者(在本例中为 openweathermap)不允许,您仍然可以通过 jsonp 请求数据(有关更多详细信息,请参阅此维基百科条目:en.wikipedia.org/wiki/JSONP
【解决方案4】:

您忘记了 ajax 请求中的 dataType:"jsonp" 属性。

【讨论】:

  • 我想他没有忘记,他为什么要打字?它有什么作用?
  • en.wikipedia.org/wiki/Same_origin_policy - jsonp 允许页面通过将
  • 关于同源政策的维基百科文章链接绝不是对 OP 问题及其解决问题的合理解释。
  • 我不明白你..如果你必须接收来自不同域的数据,你会选择 jsonp 或 cors,因为 cors 在移动设备中是新的,可能他的意思是 jsonp.. . 可能是我的问题错了:)
  • 我明白了,我只是建议您在答案中详细说明。我知道 CORS 和 JSONP 以及它们各自的缺点和优缺点 - 但 OP 不是。当你回答一个问题时,最好解释一下,而不是告诉他“使用 X”
【解决方案5】:

试试这个你忘了放用于跨域请求的JSONP

<!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>

【讨论】:

  • 你是什么意思“JSONP”用于跨域请求?有什么问题吗?我为什么要它?我为什么要避免它?
  • stackoverflow.com/questions/2067472/what-is-jsonp-all-about 检查此链接以获得清晰的解释,简而言之,如果我们需要跨域请求,我们使用 jsonp
  • 知道 JSONP 是什么 :) 我正在就我认为您可以/应该如何更新您的答案提出建议 - StackOverflow 不鼓励仅代码答案 - 尝试解释理由.
  • 用户有时需要解决方案而不是其细节。欢迎大家用更简单的方式解释jsonp。
猜你喜欢
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 2014-01-11
  • 2016-01-10
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
相关资源
最近更新 更多