jquery AJAX 完成后获取存储的JSON数据

xghobddn  于 2022-12-18  发布在  jQuery
关注(0)|答案(2)|浏览(173)

我目前正在做一个关于Jquery、 AJAX 和JSON的练习。我已经找到了一些获取数据的方法,但是现在我想把这些数据从JSON存储到一个变量中。据我所知,JSON只是一个庞大的对象数组。
我的JSON文件看起来像这样:

{
    "Products" : [{
            "Id": 11,
            "Name": "Keyboard",
            "Description": "Microsoft Keyboard",
            "PriceExVat": 199.95,
            "QtyInStock": 11
        },
        {
            "Id": 211,
            "Name": "Mouse",
            "Description": "Microsoft 3 button Mouse with scroller",
            "PriceExVat": 199.95,
            "QtyInStock": 30
        },
        {
            "Id": 35,
            "Name": "TowerCase",
            "Description": "Mini Tower Case with 450W power unit",
            "PriceExVat": 600.95,
            "QtyInStock": 23
        },
        {
            "Id": 58,
            "Name": "Monitor",
            "Description": "17inch LCD monitor",
            "PriceExVat": 1499.95,
            "QtyInStock": 12
        }]
}

我的Jquery代码如下所示:

var products;           
        $(document).ready(function(){       
            $.ajax({
                type: 'GET',
                url: 'data/Products.json',
                data: { get_param: 'value'},
                dataType: 'json',
                complete: function(data){
                    products = data; //Store JSON data
                }
            });
        });

        $(document).ajaxComplete(function(){
            alert(products); //returns object [Object]. When attempting to get data here like products[0].Name, an error occurs saying that Name does not exist
        });

我之所以这样写代码是因为我知道 AJAX 是异步的javascript和xml,所以如果我使用success : function(){...},就不能保证我的数据会保存到变量products中(也就是一个时间问题)。
所以我为 AJAX 设置了代码,让它在操作完成时存储数据。这将激发ajaxComplete()事件,理论上允许我访问我保存到变量中的数据。
这里有一个小问题,我的问题的原因是,如果我alert(products),我会得到回应

稍微修改一下代码(因为现在我认为应该在该变量中存储一些内容),将代码修改为alert(products.Products[0].Name);,会抛出一个错误(意味着该变量可能未定义)

有没有什么建议大家可以告诉我,让我去获取数据?这个变量的目的是我希望使用它来分页到我的表中,并且通过使用存储在变量中的数据来减少对json文件(以后可能会变成远程托管文件)的调用量。

编辑已将警报更改为console.Log

对象{就绪状态:4、设置请求头:函数,getAllResponseHeaders:函数,获取响应标头:函数,覆盖MIME类型:函数...}
不是我想看到的。

编辑显然,我甚至未能正确显示日志。

Object {readyState: 4, setRequestHeader: function, getAllResponseHeaders: function, getResponseHeader: function, overrideMimeType: function…}
abort: function (a){a=a||"abort",p&&p.abort(a),w(0,a);return this}
always: function (){i.done.apply(i,arguments).fail.apply(i,arguments);return this}
complete: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
done: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
error: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
fail: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
getAllResponseHeaders: function (){return s===2?n:null}
getResponseHeader: function (a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c}
isRejected: function (){return!!i}
isResolved: function (){return!!i}
overrideMimeType: function (a){s||(d.mimeType=a);return this}
pipe: function (a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()}
progress: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
promise: function (a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}
readyState: 4
responseText: "{
↵   "Products" : [{
↵           "Id": 11,
↵           "Name": "Keyboard",
↵           "Description": "Microsoft Keyboard",
↵           "PriceExVat": 199.95,
↵           "QtyInStock": 11
↵       },
↵       {
↵           "Id": 211,
↵           "Name": "Mouse",
↵           "Description": "Microsoft 3 button Mouse with scroller",
↵           "PriceExVat": 199.95,
↵           "QtyInStock": 30
↵       },
↵       {
↵           "Id": 35,
↵           "Name": "TowerCase",
↵           "Description": "Mini Tower Case with 450W power unit",
↵           "PriceExVat": 600.95,
↵           "QtyInStock": 23
↵       },
↵       {
↵           "Id": 58,
↵           "Name": "Monitor",
↵           "Description": "17inch LCD monitor",
↵           "PriceExVat": 1499.95,
↵           "QtyInStock": 12
↵       },
↵       {
↵           "Id": 234,
↵           "Name": "Laptop",
↵           "Description": "Acer Core I5 Laptop",
↵           "PriceExVat": 6999.95,
↵           "QtyInStock": 7
↵       },
↵       {
↵           "Id": 789,
↵           "Name": "CarryCase",
↵           "Description": "Targus Carry Case",
↵           "PriceExVat": 399.95,
↵           "QtyInStock": 20
↵       },
↵       {
↵           "Id": 7,
↵           "Name": "Harddrive",
↵           "Description": "1TB External Hard Drive",
↵           "PriceExVat": 999.95,
↵           "QtyInStock": 100
↵       },
↵       {
↵           "Id": 51,
↵           "Name": "Projector",
↵           "Description": "HD Projector",
↵           "PriceExVat": 4995.95,
↵           "QtyInStock": 1
↵       },
↵       {
↵           "Id": 901,
↵           "Name": "Joystick",
↵           "Description": "Microsoft Joystick",
↵           "PriceExVat": 400.95,
↵           "QtyInStock": 2
↵       },
↵       {
↵           "Id": 500,
↵           "Name": "USBCable",
↵           "Description": "3m USB-toUSB cable",
↵           "PriceExVat": 80.95,
↵           "QtyInStock": 5
↵       }]
↵}"
setRequestHeader: function (a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this}
state: function (){return e}
status: 200
statusCode: function (a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this}
statusText: "OK"
success: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
then: function (a,b,c){i.done(a).fail(b).progress(c);return this}
__proto__: Object

p4tfgftt

p4tfgftt1#

所以我摸索了一下,找到了parseJSON方法,从 AJAX 响应中看到的数据中,我想我可以获取Ajax响应文本(这是我需要的数据),将其存储在变量中,然后将其解析为JSON。
请看工作成果:

var products;           
        $(document).ready(function(){       
            $.ajax({
                type: 'GET',
                url: 'data/Products.json',
                data: { get_param: 'value'},
                dataType: 'json',
                complete: function(data){
                    products = data;
                }
            });
        });

        $(document).ajaxComplete(function(){            
            products = $.parseJSON(products.responseText); //Takes AJAX Reponse Text and parses it to JSON
            console.log(products.Products[0].Name);
        });
rxztt3cl

rxztt3cl2#

您的complete函数有一个参数data,但实际上它是一个jQueryXHR对象,如果您的服务器将内容类型设置为application/json,您应该可以只使用products = data.responseJSON,而且,我会将变量名从data更改为更像xhr的名称。
https://api.jquery.com/jQuery.ajax/
请参见关于complete方法的部分以及Data Types部分的JSON部分。
如果我是你,我会这样写:

$(document).ready(function(){       
  $.getJSON('data/Products.json?get_param=value').
    done(function(data){
      console.log(data.Products[0].name);
    });
});

有几件事要注意:
1.去掉全局products变量。这段代码异步运行,所以你不知道什么时候使用这个变量是安全的。最好只使用Promise语法(done方法)来执行你的操作,因为一旦收到 AJAX 响应,代码就会运行,你的数据实际上就存在了。
1.只对全局代码使用ajaxComplete。它不适用于一次性的 AJAX 调用,因为它每次都会为每个Ajax调用运行。它适用于全局处理,比如在发生错误时显示消息,或者在服务器以需要登录的方式响应时显示登录表单。

  1. AJAX 的complete回调函数返回一个Jquery XHR对象,因此,如果需要解析json,就需要在该对象上使用responseJSON属性。
    1.使用Promise语法(done方法)与回调相反,因为它看起来更干净,组织总是有助于防止bug,并且如果您计划编写泛型方法和重用代码,它更具可扩展性(返回 AJAX 调用并调用它的方法比作为选项传入大量回调函数要简洁得多)此外,这里的第一个参数实际上是data,所以不需要调用responseJSON属性。
    1.在 AJAX 调用中去掉不必要的选项。GET是默认方法,所以没有必要指定它。Data Type是自动的,所以如果服务器发送正确的Content-Type头,jquery只会知道响应是json。
    1.如果可以的话,坚持使用快捷方法。通过使用getJSON,您可以获得一些以前手动指定的属性,并且仍然显式地指定它们,但以一种简化的方式。getJSON仍然调用ajax
    1.避免在GET请求中使用JSON主体。这种情况并不常见,通常更倾向于只在URL中包含参数,因为GET请求是浏览器在您通过地址栏访问时所做的。主体通常只用于POST或PUT/PATCH。

相关问题