【问题标题】:Parsing a JSON server response解析 JSON 服务器响应
【发布时间】:2014-02-04 09:26:29
【问题描述】:

我正在使用 wunderground API 来练习我的 JS,并且有一个关于如何解析我拨打电话时返回的 JSON 响应的问题。

我在下面有一个简单的函数,我正在调用 URL 并接收响应并将其发送到 iframe。在 iframe 中,我看到了原始 JSON。我想知道的是如何解析 JSON 并在 iframe 中显示解析的信息。 (或者更简单的 div)

我假设它是 JSON.parse 的一些变体,但我无法让它以我想要的方式工作。

另外我更喜欢避免使用 jquery 我想使用常规 JS。

  function conditions(){
    var zip = document.getElementById("zip").value;
    var url = "http://api.wunderground.com/api/<API_KEY>/conditions/q/" + zip + ".json"
    {
    window.open(url,"frame");
    }

更新:这就是我现在所拥有的。我知道我在执行这个错误。我也仍然遇到同源问题,不得不绕过 Chrome 安全性进行测试。任何建议表示赞赏。

function conditions() {

GET_JSON = function(callback){
var c = document.getElementById("zip").value;
var x = new String("http://api.wunderground.com/api/KEY/conditions/q/" + c + ".json" +"?callback=JSONCallback");
    var req = new XMLHttpRequest();
    req.open("GET", x, true);
    req.onreadystatechange = function(){
        if(this.readyState==4){
            callback(JSON.parse(req.responseText));
        }
    }
    req.send(null);
}
JSONCallback = function(JSONObj){
    alert(JSONObj);
};
GET_JSON(JSONCallback);
}

【问题讨论】:

  • 您不使用 window.open 或 iframe 请求 JSON。您将需要使用 XMLHttpRequest 对象,并希望它们支持 CORS,因为它们具有相同的来源策略。如果没有,希望他们支持 JSONP。
  • 你需要使用AJAX,并在onreadystatechange函数中调用JSON.parse并在新窗口中写入你想要的内容。由于 AJAX 同源策略,您可能无法执行此操作,因此您可能需要在服务器上使用代理功能。
  • 为什么要使用 iFrame 而不是 AJAX 调用?您确定他们的 API 允许跨域请求吗?如果他们不这样做,那么您将需要在您的服务器上使用代理脚本。
  • 看看我的回答,我想这就是你处理这个问题所需要的。

标签: javascript json api


【解决方案1】:

不知道wunderground 是否使用与wiki media 相同的API。但是,这里有一个示例说明如何执行 JSONP(在此处阅读:JSONP),尽管有跨域请求,您仍可以查询页面。

如果您阅读此问题:Trying to search wunderground locations with javascript, jquery, and html,您可以看到建议使用 JSONP。因此,对以下示例稍作修改即可帮助您了解从网站获取结果所需的操作。

<!DOCTYPE html>
<html>
   <head>
      <title>Wikipedia JSON Grabber</title>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width">
      <style>
         div{
            position: relative;
            background-color: white;
         }
      </style>
      <script>
         // Function call the Wikipedia API
         function doFetch() {
            var tmpScript = document.createElement("script");
            tmpScript.src = "http://en.wikipedia.org/w/api.php?" +
                    "format=json" +
                    "&callback=gotFetch" +
                    "&action=query" +
                    "&titles=json" +
                    "&prop=revisions" +
                    "&rvprop=content";
            document.body.appendChild(tmpScript);
         }

         // Callback to trigger whenever the API responds
         function gotFetch(data) {
            var parent = document.createElement("div"),
                    depth = 0;
            document.body.appendChild(parent);
            console.log("Got data");
            for (var t in data) {
               console.log(data[t]);
               printData(data, parent, depth);
            }
         }

         // Recursively print out the object received to console
         function printData(data, parent, depth) {
            for (var prop in data) {

               var newDiv = document.createElement("div");
               newDiv.style.left = (10 * (depth++)) + "px";
               parent.appendChild(newDiv);

               if (typeof data[prop] === "object") {
                  newDiv.innerHTML = prop;
                  printData(data[prop], newDiv, depth);
               } else {
                  newDiv.innerHTML = data[prop];
               }
            }
         }

         function main() {
            doFetch();
         }
      </script>
   </head>
   <body onload="main();">
      <div></div>
   </body>
</html>

【讨论】:

    【解决方案2】:

    我从 wunderground 获得了一个示例 json url:

    var url = "http://api.wunderground.com/api/<API_KEY>/conditions/q/CA/San_Francisco.json";
    

    它的输出json是:

    {"response":{"version":"0.1","termsofService":"http://www.wunderground.com/weather/api/d/terms.html","features":{"conditions":1}},"current_observation":{"image":{"url":"http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png","title":"Weather Underground","link":"http://www.wunderground.com"},"display_location":{"full":"San Francisco, CA","city":"San Francisco","state":"CA","state_name":"California","country":"US","country_iso3166":"US","zip":"94101","magic":"1","wmo":"99999","latitude":"37.77500916","longitude":"-122.41825867","elevation":"47.00000000"},"observation_location":{"full":"SOMA - Near Van Ness, San Francisco, California","city":"SOMA - Near Van Ness, San Francisco","state":"California","country":"US","country_iso3166":"US","latitude":"37.773285","longitude":"-122.417725","elevation":"49 ft"},"estimated":{},"station_id":"KCASANFR58","observation_time":"Last Updated on January 15, 12:12 PM PST","observation_time_rfc822":"Wed, 15 Jan 2014 12:12:06 -0800","observation_epoch":"1389816726","local_time_rfc822":"Wed, 15 Jan 2014 12:12:10 -0800","local_epoch":"1389816730","local_tz_short":"PST","local_tz_long":"America/Los_Angeles","local_tz_offset":"-0800","weather":"Partly Cloudy","temperature_string":"69.8 F (21.0 C)","temp_f":69.8,"temp_c":21.0,"relative_humidity":"28%","wind_string":"From the WNW at 2.0 MPH","wind_dir":"WNW","wind_degrees":295,"wind_mph":2.0,"wind_gust_mph":0,"wind_kph":3.2,"wind_gust_kph":0,"pressure_mb":"1026","pressure_in":"30.29","pressure_trend":"-","dewpoint_string":"35 F (2 C)","dewpoint_f":35,"dewpoint_c":2,"heat_index_string":"NA","heat_index_f":"NA","heat_index_c":"NA","windchill_string":"NA","windchill_f":"NA","windchill_c":"NA","feelslike_string":"69.8 F (21.0 C)","feelslike_f":"69.8","feelslike_c":"21.0","visibility_mi":"10.0","visibility_km":"16.1","solarradiation":"--","UV":"3","precip_1hr_string":"0.00 in ( 0 mm)","precip_1hr_in":"0.00","precip_1hr_metric":" 0","precip_today_string":"0.00 in (0 mm)","precip_today_in":"0.00","precip_today_metric":"0","icon":"partlycloudy","icon_url":"http://icons-ak.wxug.com/i/c/k/partlycloudy.gif","forecast_url":"http://www.wunderground.com/US/CA/San_Francisco.html","history_url":"http://www.wunderground.com/weatherstation/WXDailyHistory.asp?ID=KCASANFR58","ob_url":"http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.773285,-122.417725"}}
    

    那么现在我们应该如何获得这个输出!?我们有两种不同的解决方案:

    1- 旧的解决方案是使用 ajax 将 json 作为字符串获取,然后将其解析为对象,如下所示:

    GET_JSON = function(callback){
        var req = new XMLHttpRequest();
        req.open("GET", url, true);
        req.onreadystatechange = function(){
            if(this.readyState==4){
                callback(JSON.parse(req.responseText));
            }
        }
        req.send(null);
    }
    JSONCallback = function(JSONObj){
        alert(JSONObj);
    };
    GET_JSON(JSONCallback);
    

    但这里的问题是,如果您在您的网站中这样做,您将面临以下错误:

    No 'Access-Control-Allow-Origin' header is present on the requested resource.
        Origin 'http://mydomain.com' is therefore not allowed access.
    

    2- 没问题,wunderground weather api 支持JSONP,它会帮助我们解决它,我们只需要打一个JSONP 调用,这里的棘手点是,我们不会使用常规的 ajax 解决方案不再:

    GET_JSON = function(callback){
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = url + "?callback=" + callback;
        document.body.appendChild(script);
    }
    window.JSONCallback = function(JSONObj){
        alert(JSONObj);
    };
    GET_JSON("JSONCallback");
    

    有一个非常棘手的点非常重要。如果你检查最后一行而不是将回调对象作为参数传递,我已经传递了它的名称,这是为什么呢?

    答案是,如果我们想要一个 JSONP 调用,我们必须使用 callback queryString 传递回调函数的名称。像这样:

    url = "http:// ... .json?callback=JSONCallback";
    

    这就是访问 json 对象所需要知道的全部内容,而无需解析字符串。

    【讨论】:

    • 感谢您为帮助我所做的努力。但是,我不确定如何实施您的建议。我更新了我现在在主帖中的脚本。我现在需要解决什么问题?
    • 你在代码中混合了 ajax 调用和 jsonp,如果你用我的第二个 GET_JSON(不使用 XmlHttpRequest)替换 GET_JSON,你的问题就解决了。
    猜你喜欢
    • 2013-08-05
    • 1970-01-01
    • 2012-07-09
    • 2019-07-18
    • 1970-01-01
    • 2013-01-10
    • 2013-02-13
    • 2011-02-10
    • 1970-01-01
    相关资源
    最近更新 更多