从远程服务器获取数据时,服务器的响应通常是 JSON 格式。在这个快速提示中,我将演示如何使用 JavaScript 解析服务器的响应,从而访问您需要的数据。
这个过程通常包括两个步骤:将数据解码为本地结构(例如数组或对象),然后使用 JavaScript 的内置方法之一循环该数据结构。在本文中,我将使用大量可运行的示例来介绍这两个步骤。
目录
在我们了解如何处理 JSON 之前,让我们花点时间了解它是什么(以及它不是什么)。
使用Object.entries,Object.values或Object.entries
什么是 JSON?
在我们了解如何处理 JSON 之前,让我们花点时间了解它是什么(以及它不是什么)。
JSON代表Java S cript Object Notation 。_ 它是一种独立于语言、基于文本的格式,通常用于在 Web 应用程序中传输数据。JSON 受到 JavaScript Object Literal 表示法的启发,但两者之间存在差异。例如,在 JSON 中,键必须使用双引号引起来,而在对象文字中则不是这样。
有两种方式可以将数据存储在 JSON 中:
- 名称/值对的集合(又名 JSON 对象)
- 有序的值列表(又名 JSON 数组)
从 Web 服务器接收数据时,数据始终是字符串,这意味着您的工作是将其转换为您可以使用的数据结构。
从远程 API 获取 JSON
在以下示例中,我们将使用出色的icanhazdadjoke API,正如您在其文档中所读到的,发出Accept
标头设置为的 GET 请求application/json
将看到 API 返回 JSON 有效负载。
让我们从一个简单的例子开始:
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(typeof xhr.responseText);
console.log(xhr.responseText);
}
};
xhr.open('GET', 'https://icanhazdadjoke.com/', true);
xhr.setRequestHeader('Accept', 'application/json');
xhr.send(null);
// string
// {"id":"daaUfibh","joke":"Why was the big cat disqualified from the race? Because it was a cheetah.","status":200}
如我们所见,服务器返回给我们一个字符串。我们需要先将其解析为 JavaScript 对象,然后才能遍历其属性。我们可以用 JSON.parse()做到这一点:
if (xhr.readyState === XMLHttpRequest.DONE) {
const res = JSON.parse(xhr.responseText);
console.log(res);
};
// Object { id: "fiyPR7wPZDd", joke: "When does a joke become a dad joke? When it becomes apparent.", status: 200 }
一旦我们将响应作为 JavaScript 对象,我们可以使用许多方法来循环它。
使用for...in
循环
for...in
循环遍历对象的所有可枚举属性:
const res = JSON.parse(xhr.responseText);
for (const key in res){
if(obj.hasOwnProperty(key)){
console.log(`${key} : ${res[key]}`)
}
}
// id : H6Elb2LBdxc
// joke : What's blue and not very heavy? Light blue.
// status : 200
请注意,
for...of
循环将遍历整个原型链,因此我们在这里使用hasOwnProperty
以确保属性属于我们的res
对象。
使用Object.entries
,Object.values
或Object.entries
上面的另一种方法是使用Object keys(),Object values (),Object.
或entries()
之一。这些将返回一个数组,然后我们可以对其进行迭代。
我们来看看使用Object.entries
. 这将返回我们传递给它的对象的键/值对数组:
const res = JSON.parse(xhr.responseText);
Object.entries(res).forEach((entry) => {
const [key, value] = entry;
console.log(`${key}: ${value}`);
});
// id: SvzIBAQS0Dd
// joke: What did the pirate say on his 80th birthday? Aye Matey!
// status: 200
请注意,该const [key, value] = entry;
语法是ES2015 中引入该语言的数组解构示例。
这更简洁,避免了前面提到的原型问题,并且是我循环通过 JSON 响应的首选方法。
使用获取 API
虽然上面使用XMLHttpRequest
对象的方法工作得很好,但它很快就会变得笨拙。我们可以做得更好。
fatch API是一个基于 Promise的API,它支持更简洁、更简洁的语法,并帮助您远离回调地狱。它提供了fetch()
在对象上定义的方法window
,您可以使用它来执行请求。此方法返回一个 Promise,您可以使用它来检索请求的响应。
让我们重写之前的示例来使用它:
(async () => {
const res = await fetch('https://icanhazdadjoke.com/', {
headers: { Accept: 'application/json' },
});
const json = await res.json();
Object.entries(json).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
})();
// id: 2wkykjyIYDd
// joke: What did the traffic light say to the car as it passed? "Don't look I'm changing!"
// status: 200
Fetch API 返回一个响应流。这不是 JSON,因此JSON.parse()
我们不需要尝试调用它,而是需要使用它的response.json()函数。这将返回一个 Promise,该 Promise 解析为将响应的正文文本解析为 JSON 的结果。
处理数组
正如文章开头所提到的,值的有序列表(也称为数组)是有效的 JSON,所以在结束之前,让我们来看看如何处理这样的响应。
对于最后一个示例,我们将使用GitHubD的REST API来获取用户存储库的列表:
(async () => {
async function getRepos(username) {
const url = `https://api.github.com/users/${username}/repos`;
const response = await fetch(url);
const repositories = await response.json();
return repositories;
}
const repos = await getRepos('jameshibbard');
console.log(repos);
})();
// Array(30) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]
如您所见,API 返回了一个对象数组。要访问每个单独的对象,我们可以使用常规forEach
方法:
repos.forEach((repo) => {
console.log(`{$repo.name} has ${repo.stargazers_count} stars`);
});
// Advanced-React has 0 stars
// angular2-education has 0 stars
// aurelia-reddit-client has 3 stars
// authentication-with-devise-and-cancancan has 20 stars
// ...
或者,您当然可以使用上面讨论的任何方法来循环遍历对象的所有属性并将它们记录到控制台:
repos.forEach((repo) => {
Object.entries(repo).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
});
// name: Advanced-React
// full_name: jameshibbard/Advanced-React
// private: false
// ...
结论
在这个快速提示中,我们已经了解了 JSON 是什么。我已经演示了如何将来自服务器的 JSON 响应解析为原生数据结构(例如数组或对象),以及如何循环访问这样的结构,以便访问其中包含的数据。