【问题标题】:Issue Reading JSON问题读取 JSON
【发布时间】:2012-08-02 15:04:49
【问题描述】:

我在阅读以下 JSON 时遇到了困难(基本上没有错误,也没有任何反应),并希望能在识别函数问题时获得帮助。我不清楚 ajax 是否成功地抓住了它,或者它只是在之后没有正确读取它。任何帮助将不胜感激!

这是 JSON 响应的结构:

   [{"attributes":{"type":"Account","url":"/services/data/v25.0/sobjects/Account/00130000015KJlWAAW"},"id":"00130000015KJlWAAW","locname":"Central Valley Ag","address":"607 North Robinson","city":"Hartington","state":"NE","postal":"68739","phone":"402-254-3354","web":"","lat":"42.627212","lng":"-97.269283"},{"attributes":{"type":"Account","url":"/services/data/v25.0/sobjects/Account/00130000015KJlXAAW"},"id":"00130000015KJlXAAW","locname":"Central Valley Ag","address":"709 Centennial Rd","city":"Wayne","state":"NE","postal":"68787","phone":"402-375-3510","web":"","lat":"42.235756","lng":"-96.998321"}]

这是处理 JSON 的脚本部分:

   function mapping(orig_lat, orig_lng, origin) {
                $(function () {
                    var dataType;
                    //jsonData is set to true
                    if (settings.jsonData == true) {
                        dataType = "jsonp";
                    } else {
                        dataType = "xml";
                    }
                    $.ajax({
                        type: "GET",
                        url: settings.dataLocation,
                        dataType: dataType,
                        crossDomain: true,                            
                        error: function(jqXHR, textStatus, errorThrown) {   
                    alert('Error Message: '+textStatus);
                    alert('HTTP Error: '+errorThrown);
                },
                        success: function (data) {
                            //After the store locations file has been read successfully
                            var i = 0;

                            if (settings.jsonData == true) {
                                var data = $.parseJSON(data);
                                //Process JSON
                                $.each(data, function () {
                                    var name = this.locname;
                                    var lat = this.lat;
                                    var lng = this.lng;
                                    var address = this.address;
                                    var address2 = this.address2;
                                    var city = this.city;
                                    var state = this.state;
                                    var postal = this.postal;
                                    var phone = this.phone;
                                    var web = this.web;
                                    web = web.replace("http://", "");
                                    var distance = GeoCodeCalc.CalcDistance(orig_lat, orig_lng, lat, lng, GeoCodeCalc.EarthRadiusInMiles);
                                    //Create the array
                                    locationset[i] = new Array(distance, name, lat, lng, address, address2, city, state, postal, phone, web);
                                    i++;
                                });
                            } else {
                                //Process XML
                                $(data).find('marker').each(function () {
                                    //Take the lat lng from the user, geocoded above
                                    var name = $(this).attr('name');
                                    var lat = $(this).attr('lat');
                                    var lng = $(this).attr('lng');
                                    var address = $(this).attr('address');
                                    var address2 = $(this).attr('address2');
                                    var city = $(this).attr('city');
                                    var state = $(this).attr('state');
                                    var postal = $(this).attr('postal');
                                    var phone = $(this).attr('phone');
                                    var web = $(this).attr('web');
                                    web = web.replace("http://", "");
                                    var distance = GeoCodeCalc.CalcDistance(orig_lat, orig_lng, lat, lng, GeoCodeCalc.EarthRadiusInMiles);
                                    //Create the array
                                    locationset[i] = new Array(distance, name, lat, lng, address, address2, city, state, postal, phone, web);
                                    i++;
                                });
                            }

更新:我添加了一个 ajax 错误处理程序作为状态,并在页面加载时得到以下 parseerror:

HTTP 错误:错误: jQuery172036075869924388826_1343923258757 未被调用

然后,当我尝试运行该函数时,我收到以下错误:

Uncaught TypeError: Property 'alert' of object [object Window] is not a function          dealer-locator-iframe2:273
$.fn.storeLocator.each.$.ajax.error dealer-locator-iframe2:273
f.Callbacks.o jquery.min.js:2
f.Callbacks.p.fireWith jquery.min.js:2
w jquery.min.js:4
f.ajaxTransport.send.d.onload.d.onreadystatechange

【问题讨论】:

  • @Onheiron - if (settings.jsonData == true) { dataType = "jsonp"; 中的“jsonp”
  • 您的 JSON 用 [] 括起来,这表明它可能被解释为对象数组。尝试调用 this[0].locname ... 并为之前的评论感到抱歉,我读得不太好:D

标签: javascript jquery ajax json jsonp


【解决方案1】:

您似乎需要在 data 变量上运行 $.parseJSONdata 以 JSON 字符串的形式返回,您需要将其转换为 JavaScript 对象字面量。

例子:

var obj = $.parseJSON('{"name":"John"}');
alert( obj.name === "John" );

因此,在您的 success 函数中将其放在 if (settings.jsonData == true) 之后:

var data = $.parseJSON(data);

您没有收到任何错误的原因是因为 $.each(function() {....}); 没有循环,因为没有任何东西可以在字符串上循环。

有一种非常简单的方法可以测试data 变量的数据类型。在 success 函数的开头使用它:

alert(typeof(data));

如果您返回了string,那么您就知道这就是问题所在。

【讨论】:

  • dataType 可以设置为 JSON,但他仍然返回一串 JSON。该 JSON 字符串需要被解析(即安全地评估)为对象表示法。
  • 正确的解决方案,但我认为放置这段代码的最佳位置是在$.each 之前-if(setting.jsonData) 内部,因为如果有XML 数据不会造成任何问题:)
  • 哦,你是对的,我错过了 JSON 与 XML 的 if/then 语句,答案已更新。
  • @ElliotB。当我 alert(typeof(data)); 时,我没有得到任何返回。所以我想我可能需要将 ajax 错误处理程序设置为 epascarello 状态。另外,我添加了 var data = $.parseJSON(data);再次没有发生任何错误。
  • @Onheiron 我更新了我的帖子以包含我看到的错误 - 你以前见过这个吗?
【解决方案2】:

$.each之前添加这一行

data = eval("("+data+")");

您的其余代码将正常工作...

为什么您的代码不起作用? 原因 - 因为您试图在 string 上运行循环。 首先将string 转换为JSON objecteval()string 转换为 javascript 对象。

【讨论】:

  • 运行 eval 有效,但不是处理入站 JSON 字符串的最安全方法,首选 parseJSON 等解析方法。
  • 我认为@Elliot B. 方法是正确的,如果这是问题,通常 eval() 应谨慎使用。
  • 哦!感谢您提供信息,我不知道 :) 你能告诉我eval() 可能会遇到什么问题吗?因为我总是使用它......我想开始使用$.parseJSON 代替......我并不总是使用jQuery btw,所以我坚持使用eval().. 我从未观察到eval() 有任何问题虽然:)..只是好奇...
  • 简单地 eval() 评估一个字符串,就好像它是一个命令本身,但你不能确定里面有什么......假设你不知道你的服务器响应可能是' {json:"goodJSO"} + mean code' 如果你调用 parseJSON 它只会失败,如果你调用 eval() 它将执行其中的平均代码。
  • 使用 eval 时,您很容易受到注入攻击,黑客会创建包含 JS 命令而不是正确 JSON 的虚假 AJAX 响应。 $.parseJSON 旨在防止执行注入的命令,而 eval 只是执行所有内容而不进行检查。
【解决方案3】:

您的 JSON 看起来像一个对象数组,您可以通过它周围的 [] 来判断。它是一个只有一个元素的数组,但如果你写会出错

json.key

因为 json 不是一个对象,而是一个对象数组,所以 json.key 看起来你正在调用数组中不存在的一些 fncion“键”。您应该首先使用 json[0] 选择真实对象本身

myJson = json[0]

然后

value = myJson.key1

如果您使用一些外部 API,很可能是我之前遇到过的这个问题

【讨论】:

  • 如果您查看 JSONP with jQuery 部分下的 devlog.info/2010/03/10/cross-domain-ajax,它说它应该很容易处理。我开始相信还有另一个问题。但我看到数据非常好。这是我工作的 URL:microessentials.com/dealer-locator2
  • 但是你尝试过我的建议了吗?这不是错误或问题,只是服务不知道有多少记录与您的 get 查询匹配,因此它将每条记录放在 JSON 数组中,当我说它是一个数组时,并不意味着它不是正确的 JSON,只是你应该期待一个或多个匹配一张脸的事实,你必须处理它们
  • 是的,我试过了,但有问题。这似乎是 JSONP 的回调问题。它一直告诉我它不能调用数据。
  • 好的,我认为它不会有太大变化,但试试 .getJSON,它应该会自动处理输入api.jquery.com/jQuery.getJSON 还有那个 setting.dataLocation 到底是什么?
  • 是的,我最初有 .getJSON 并将其更改为 JSONP 作为解决方案。至于.dataLocation,mosaicco.force.com/siteforce/activeretailaccounts
猜你喜欢
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多