Working with JSON data
先决条件: | 基本的计算机素养,对HTML和CSS的基本了解,熟悉JavaScript基础知识(请参见第一步和构建块 / a>)和OOJS基础知识(请参见对象简介)。 |
---|---|
目的: | 要了解如何使用存储在JSON中的数据,并创建自己的JSON对象。 |
不,真的,什么是JSON?
JSON 是一种数据格式,遵循JavaScript对象语法,该语法由 a class ="external"href ="https://en.wikipedia.org/wiki/Douglas_Crockford"> Douglas Crockford 。 即使它是基于JavaScript语法,它可以独立于JavaScript使用,并且许多编程环境具有读取(解析)和生成JSON的能力。
JSON可以作为对象或字符串存在 - 前者用于从JSON读取数据,后者用于在网络上发送JSON。 这不是一个大问题 - JavaScript提供了一个全局 JSON 对象 有可用于在两者之间转换的方法。
JSON对象可以存储在自己的文件中,基本上只是一个扩展名为 .json
和 mozilla.org/zh-CN/docs/Glossary/MIME_type\"> MIME类型的 application / json
。
JSON结构
我们在上面已经暗示,JSON对象基本上是一个JavaScript对象,这是最正确的。 您可以在JSON中包含与标准JavaScript对象(字符串,数字,数组,布尔值和其他对象字面值)中相同的基本数据类型。 这允许您构造数据层次结构,如下所示:
{ "squadName" : "Super hero squad", "homeTown" : "Metro City", "formed" : 2016, "secretBase" : "Super tower", "active" : true, "members" : [ { "name" : "Molecule Man", "age" : 29, "secretIdentity" : "Dan Jukes", "powers" : [ "Radiation resistance", "Turning tiny", "Radiation blast" ] }, { "name" : "Madame Uppercut", "age" : 39, "secretIdentity" : "Jane Wilson", "powers" : [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] }, { "name" : "Eternal Flame", "age" : 1000000, "secretIdentity" : "Unknown", "powers" : [ "Immortality", "Heat Immunity", "Inferno", "Teleportation", "Interdimensional travel" ] } ] }
如果我们将这个对象加载到JavaScript程序中,保存在一个叫做 superHeroes
的变量中,我们就可以使用我们在 "/ webstart / Objects / Basics"> JavaScript对象基础文章。 例如:
superHeroes.hometown superHeroes["active"]
要在层次结构中进一步访问数据,您只需将所需的属性名称和数组索引链接在一起。 例如,要访问成员列表中列出的第二个英雄的第三超级大国,您可以这样做:
superHeroes["members"][1]["powers"][2]
- First we have the variable name —
superHeroes
. - Inside that we want to access the
members
property, so we use["members"]
. -
members
contains an array populated by objects. We want to access the second object inside the array, so we use[1]
. - Inside this object, we want to access the
powers
property, so we use["powers"]
. - Inside the
powers
property is an array containing the selected hero's superpowers. We want the third one, so we use[2]
.
注意:我们已在上面的 /json/JSONTest.html\">JSONText.html 示例(请参阅 /json/JSONTest.html\">源代码)。 尝试加载,然后通过浏览器的JavaScript控制台访问变量中的数据。
数组为JSON
上面我们说"我们已经暗示JSON对象基本上是一个JavaScript对象,这是正确的" - 我们说"大多数正确"的原因是因为数组也可以是一个有效的JSON对象,例如:
[ { "name" : "Molecule Man", "age" : 29, "secretIdentity" : "Dan Jukes", "powers" : [ "Radiation resistance", "Turning tiny", "Radiation blast" ] }, { "name" : "Madame Uppercut", "age" : 39, "secretIdentity" : "Jane Wilson", "powers" : [ "Million tonne punch", "Damage resistance", "Superhuman reflexes" ] } ]
上面是完全有效的JSON。 你只需要从数组索引开始访问数组项,例如 [0] ["powers"] [0]
。
其他说明
- JSON is purely a data format — it contains only properties, no methods.
- JSON requires double quotes to be used to be valid. It is safest to write it with double quotes, not single quotes.
- Even a single misplaced comma or colon can cause a JSON file to go wrong, and not work. You should be careful to validate any data you are attempting to use (although computer-generated JSON is less likely to include errors, as long as the generator program is working correctly). You can validate JSON using an application like JSONLint.
- JSON can actually take the form of any data type that is valid for inclusion inside a standard JSON object, not just arrays or objects. So for example, a single string or number would be a valid JSON object. Not that this would be particularly useful...
主动学习:通过JSON示例
因此,让我们通过一个例子来说明如何在网站上使用一些JSON数据。
入门
首先,制作我们的英雄的本地副本。 html 和 style.css a>文件。 后者包含一些简单的CSS来为我们的页面设计样式,而前者包含一些非常简单的body HTML:
<header> </header> <section> </section>
加上 < script>
元素,以包含我们将在此处撰写的JavaScript代码 行使。 目前它只包含两行,它们引用了 < header>
和 < section>
元素并将其存储在变量中:
var header = document.querySelector('header'); var section = document.querySelector('section');
我们已将我们的JSON数据提供给我们的GitHub,网址为: https:/ /mdn.github.io/learning-area/javascript/oojs/json/superheroes.json 。
我们将把它加载到我们的页面,并使用一些漂亮的DOM操作来显示它,像这样:
加载我们的JSON
要将我们的JSON加载到我们的网页中,我们将使用名为 XMLHttpRequest
的API(通常称为 XHR )。 这是一个非常有用的JavaScript对象,它允许我们通过JavaScript(例如图像,文本,JSON,甚至HTML片段)来从服务器检索资源,这意味着我们可以更新内容的小部分,而不必重新加载整个 页。 这导致更响应的网页,并听起来令人兴奋,但不幸的是超出了本文的范围,教更多的细节。
- To start with, we are going to store the URL of the JSON file we want to retrieve in a variable. Add the following at the bottom of your JavaScript code:
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
- To create a request, we need to create a new request object instance from the
XMLHttpRequest
constructor, using thenew
keyword. Add the following below your last line:var request = new XMLHttpRequest();
- Now we need to open a new request using the
open()
method. Add the following line:request.open('GET', requestURL);
这至少需要两个参数 - 还有其他可选参数可用。 对于这个简单的例子,我们只需要两个强制的:
- The HTTP method to use when making the network request. In this case
GET
is fine, as we are just retrieving some simple data. - The URL to make the request to — this is the URL of the JSON file that we stored earlier.
- The HTTP method to use when making the network request. In this case
- Next, add the following two lines — here we are setting the
responseType
to JSON, so the server will know we want a JSON object returned, and sending the request with thesend()
method:request.responseType = 'json'; request.send();
- The last bit of this section involves waiting for the response to return from the server, then dealing with it. Add the following code below your previous code:
request.onload = function() { var superHeroes = request.response; populateHeader(superHeroes); showHeroes(superHeroes); }
这里我们存储对我们的请求的响应(可在 响应
> 属性)在一个名为 superHeroes
的变量中; 这个变量现在将包含我们的JSON! 然后,我们将该JSON传递给两个函数调用 - 第一个将用正确的数据填充< header>
,而第二个将为团队中的每个英雄创建一个信息卡, 将其插入到< section>
中。
我们将代码包装在事件处理程序中,当load事件触发请求对象时运行(参见 XMLHttpRequestEventTarget / onload"> onload
) - 这是因为load事件在响应成功返回时触发; 这样做保证 request.response
一定会可用,当我们试图做一些事情。
填充头
现在我们已经检索了我们的JSON数据,让我们通过写我们上面提到的两个函数来使用它。 首先,在上面的代码下面添加以下函数定义:
function populateHeader(jsonObj) { var myH1 = document.createElement('h1'); myH1.textContent = jsonObj['squadName']; header.appendChild(myH1); var myPara = document.createElement('p'); myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed']; header.appendChild(myPara); }
我们调用了参数 jsonObj
,这就是我们需要调用它里面的JSON对象。 在这里,我们首先使用创建
> createElement() ,将其< h1>
元素 href ="https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent"> textContent
等于 squadName
属性 JSON,然后使用 appendChild()将其附加到标题
。 然后,我们对一个段落进行非常类似的操作:创建它,设置其文本内容并将其附加到标题。 唯一的区别是其文本设置为包含JSON的 homeTown
和形成
属性的连接字符串。
创建英雄信息卡
接下来,在代码的底部添加以下函数,创建并显示超级英雄卡:
function showHeroes(jsonObj) { var heroes = jsonObj['members']; for(i = 0; i < heroes.length; i++) { var myArticle = document.createElement('article'); var myH2 = document.createElement('h2'); var myPara1 = document.createElement('p'); var myPara2 = document.createElement('p'); var myPara3 = document.createElement('p'); var myList = document.createElement('ul'); myH2.textContent = heroes[i].name; myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity; myPara2.textContent = 'Age: ' + heroes[i].age; myPara3.textContent = 'Superpowers:'; var superPowers = heroes[i].powers; for(j = 0; j < superPowers.length; j++) { var listItem = document.createElement('li'); listItem.textContent = superPowers[j]; myList.appendChild(listItem); } myArticle.appendChild(myH2); myArticle.appendChild(myPara1); myArticle.appendChild(myPara2); myArticle.appendChild(myPara3); myArticle.appendChild(myList); section.appendChild(myArticle); } }
首先,我们将JSON的 members
属性存储在一个新变量中。 此数组包含多个对象,其中包含每个英雄的信息。
接下来,我们使用 for循环循环访问数组中的每个对象。 对于每一个,我们:
- Create several new elements: an
<article>
, an<h2>
, three<p>
s, and a<ul>
. - Set the <h2> to contain the current hero's
name
. - Fill the three paragraphs with their
secretIdentity
,age
, and a line saying "Superpowers:" to introduce the information in the list. - Store the
powers
property in another new variable calledsuperPowers
— this contains an array that lists the current hero's superpowers. - Use another
for
loop to loop through the current hero's superpowers — for each one we create a<li>
element, put the superpower inside it, then put thelistItem
inside the<ul>
element (myList
) usingappendChild()
. - The very last thing we do is to append the
<h2>
,<p>
s, and<ul>
inside the<article>
(myArticle
), then append the<article>
inside the<section>
. The order in which things are appended is important, as this is the order they will be displayed inside the HTML.
注意:如果您无法使示例工作,请尝试参考我们的 master / javascript / oojs / json / heroes-finished.html"> heroes-finished.html 源代码(参见 -area / javascript / oojs / json / heroes-finished.html">运行实时)。
注意:如果您在使用我们用于访问JSON的点/括号符号时遇到问题,可以使用 github.io/learning-area/javascript/oojs/json/superheroes.json\">superheroes.json 文件在另一个选项卡或文本编辑器中打开,并在查看我们的JavaScript时参考它。 您还应参阅我们的 JavaScript对象基础知识文章,了解点和括号符号的更多信息。
在对象和文本之间转换
上面的例子在访问JSON方面很简单,因为我们设置XHR以JSON格式返回响应,使用:
request.responseType = 'json';
但有时我们不那么幸运 - 有时我们会收到一些格式化为文本字符串的JSON数据,我们需要将它转换为一个对象。 当我们想要发送JSON数据作为某种消息时,我们经常需要将其转换为字符串,以使其正常工作。 幸运的是,这两个问题在Web开发中非常常见,内置的 JSON / a>对象被添加到浏览器很久以前,包含以下两种方法:
-
parse()
: Accepts a JSON object in text string form as a parameter, and returns the corresponding object. -
stringify()
: Accepts a JSON object as a parameter, and returns the equivalent text string form.
您可以在我们的 > heroes-finished-json-parse.html example(see the json / heroes-finished-json-parse.html">源代码) - 这与我们之前构建的示例完全相同,只是我们设置XHR将JSON作为文本返回,然后使用 parse()
将其转换为实际的JSON对象。 代码的关键代码片段在这里:
request.open('GET', requestURL); request.responseType = 'text'; // now we're getting a string! request.send(); request.onload = function() { var superHeroesText = request.response; // get the string from the response var superHeroes = JSON.parse(superHeroesText); // convert it to an object populateHeader(superHeroes); showHeroes(superHeroes); }
正如你可能猜到的, stringify()
工作方式相反。 尝试在浏览器的JavaScript控制台中输入以下行,以便在操作中查看它:
var myJSON = { "name" : "Chris", "age" : "38" }; myJSON var myString = JSON.stringify(myJSON); myString
这里我们创建一个JSON对象,然后检查它包含什么,然后使用 stringify()
将返回值保存在一个新的变量,然后再次检查它转换为字符串。
概要
在本文中,我们为您提供了在程序中使用JSON的简单指南,包括如何创建和解析JSON,以及如何访问其中锁定的数据。 在下一篇文章中,我们将开始讨论面向对象的JavaScript。
更多建议: