Ajax 完成后获取存储的 JSON 数据
Posted
技术标签:
【中文标题】Ajax 完成后获取存储的 JSON 数据【英文标题】:Getting Stored JSON data after Ajax is Complete 【发布时间】:2013-01-25 02:29:19 【问题描述】:我目前正在做一个关于 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 文件(以后可能成为远程托管文件)的调用量。
编辑 将警报更改为控制台。日志
Object readyState: 4, setRequestHeader: function, getAllResponseHeaders: function, getResponseHeader: function, overrideMimeType: function…
不是我希望看到的。
编辑 显然我什至没有正确显示日志。
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]=breturn 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
【问题讨论】:
注意,我最近才开始使用 JQuery、Ajax 和 JSON。 console.log(data) 不提醒,然后你会在控制台中看到结构 使用console.log(products)在控制台打印出产品! 哎呀。完全不是我所期待的 你确定你的 AJAX 请求工作正常吗,因为你的代码最基本的形式工作:jsfiddle.net/Cwmt9 【参考方案1】:所以我四处寻找并找到了 parseJSON 方法。根据我在 Ajax 响应中看到的数据,我想我可以获取 Ajax ResponseText(这是我需要的数据),将其存储在变量中,然后将其解析为 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);
);
【讨论】:
如果 dataType 设置为 json,那么您应该可以使用 products = products.responseText;console.log(products.Products[0].Name);没有json。不是这样吗? 未捕获的类型错误:无法读取未定义的属性 '0' :: products = products.responseText; console.log(products.Products[0].Name); 这意味着 responseText 是一个需要转换的字符串,如果我理解正确的话。因此我将数据解析为 JSON【参考方案2】:您的complete
函数有一个参数data
,但实际上它是一个jQuery XHR 对象。如果您的服务器将内容类型设置为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);
);
);
有几点需要注意:
-
摆脱全局产品变量。此代码异步运行
所以你不知道什么时候使用这个变量是安全的。最好只使用 Promise 语法(done 方法)执行您的操作,因为一旦收到 Ajax 响应并且您的数据确实存在,该代码就会运行。
仅将
ajaxComplete
用于全局代码。它不适用于一次性的 Ajax 调用,因为它每次都会为每个 Ajax 调用运行。它适用于全局处理,例如在发生错误时显示消息,或者在服务器以意味着您需要登录的方式响应时显示登录表单。
Ajax 的 complete
回调返回一个 Jquery XHR 对象,因此如果要解析 json,则需要在其上使用 responseJSON
属性。
使用 Promise 语法(done 方法)而不是回调,因为它看起来更简洁,并且组织总是有助于防止错误,并且如果您计划编写通用方法和重用代码(返回 Ajax 调用并且从中调用方法比将许多回调函数作为选项传递要干净得多)。另外,这里的第一个参数实际上是data
,所以你不需要调用responseJSON
属性。
在您的 Ajax 调用中删除不必要的选项。 GET 是默认方法,因此没有必要指定它。数据类型是自动的,因此如果您的服务器发送正确的 Content-Type 标头,jquery 只会知道响应是 json。
如果可以,请坚持使用快捷方式。通过使用 getJSON,您可以获取一些以前手动指定的属性,并且仍然显式指定它们,但是是以简写的方式。 getJSON
仍然调用ajax
。
避免对 GET 请求使用 JSON 正文。这不是很常见,通常最好只在 URL 中包含参数,因为 GET 请求是浏览器在您通过地址栏访问时所做的。主体通常仅用于 POST 或 PUT/PATCH。
【讨论】:
以上是关于Ajax 完成后获取存储的 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 JSON 数据的 Ajax / Jquery 自动完成
jQuery TagIt(自动完成)通过 AJAX 获取 JSON 列表