In this article we’ll investigate the importance of JSON and why we should use it in our applications. We’ll see that jQuery has got us covered with a very nice convenience function.
在本文中,我们将研究JSON的重要性以及为什么要在应用程序中使用JSON。 我们将看到jQuery为我们提供了非常不错的便捷功能 。
JSON stands for JavaScript Object Notation. In simple terms JSON is a way of formatting data for, e.g., transmitting it over a network. In this article we will look at loading JSON data using an HTTP GET request (we can also use other verbs, such as POST).
JSON代表JavaScript对象符号。 简而言之,JSON是一种格式化数据的方式,例如,通过网络传输数据。 在本文中,我们将研究使用HTTP GET请求加载JSON数据(我们也可以使用其他动词,例如POST)。
Why would we choose JSON over say XML? The key advantage of using JSON is efficiency. JSON is less verbose and cluttered, resulting in fewer bytes and a faster parse process. This allows us to process more messages sent as JSON than as XML. Moreover, JSON has a very efficient and natural object representation leading to formats such as BSON, where JSON-like objects are stored in a binary format.
为什么我们选择JSON而不是XML? 使用JSON的主要优势是效率。 JSON不太冗长和混乱,从而减少了字节数并加快了解析过程。 这使我们可以处理更多的以JSON形式发送的消息,而不是XML形式的消息。 此外,JSON具有非常高效且自然的对象表示形式,从而产生了BSON之类的格式,其中类似JSON的对象以二进制格式存储。
Now let’s see how jQuery can help us load JSON-encoded data from a remote source. For the impatient among you, there’s a demo towards the end of the article.
现在,让我们看看jQuery如何帮助我们从远程源加载JSON编码的数据。 对于不耐烦的人,在本文结尾处有一个演示 。
The $.getJSON() method is a handy helper for working with JSON directly if you don’t require much extra configuration. Essentially, it boils down to the more general $.ajax() helper, with the right options being used implicitly. The method signature is:
如果您不需要太多额外的配置,则$.getJSON()方法是直接使用JSON的便捷助手。 本质上,它归结为更通用的$ .ajax()帮助器,并隐式使用了正确的选项。 方法签名为:
$.getJSON(url, data, success);Besides the required URL parameter we can pass in two optional parameters. One represents the data to send to the server, the other one a callback to trigger in case of a successful response.
除了必需的URL参数,我们还可以传入两个可选参数。 一个代表要发送到服务器的数据,另一个代表在成功响应的情况下触发的回调。
So the three parameters correspond to:
因此,这三个参数对应于:
The url parameter is a string containing the URL to which the request is sent.
url参数是一个字符串,其中包含将请求发送到的URL。
The optional data parameter is either an object or a string that is sent to the server with the request.
可选的data参数是与请求一起发送到服务器的对象或字符串。
The optional success(data, textStatus, jqXHR) parameter is a callback function executed only if the request succeeds.
可选的success(data, textStatus, jqXHR)参数是仅在请求成功时执行的回调函数。
In the simplest scenario we only care about the returned object. In this case, a potential success callback would look like this:
在最简单的情况下,我们只关心返回的对象。 在这种情况下,潜在的success回调如下所示:
function success(data) { // do something with data, which is an object }As mentioned, the same request can be triggered with the more verbose $.ajax() call. Here we would use:
如前所述,可以通过更详细的$.ajax()调用来触发相同的请求。 在这里,我们将使用:
$.ajax({ dataType: 'json', url: url, data: data, success: success });Let’s see this in practice using a little demo.
让我们在实践中使用一个小样看一下。
We will start a local server that serves a static JSON file. The object represented by this file will be fetched and processed by our JavaScript code. For the purposes of our demo we’ll use Node.js to provide the server (although any server will do). This means we’ll need the following three things:
我们将启动提供静态JSON文件的本地服务器。 该文件表示的对象将由我们JavaScript代码获取和处理。 出于演示目的,我们将使用Node.js提供服务器(尽管任何服务器都可以)。 这意味着我们需要以下三件事:
A working installation of Node.js. Node.js的有效安装。 The node package manager (npm). 节点程序包管理器(npm)。A global installation of the http-server package.
http-server软件包的全局安装。
The first two points are platform-dependent. If you need some help getting either of them set up, you might want to check out our tutorial: A Beginner’s Guide to npm — the Node Package Manager, or Node’s download page (npm comes bundled with Node).
前两点取决于平台。 如果您需要帮助来设置它们中的任何一个,则可能需要查看我们的教程: npm入门指南— Node Package Manager或Node的下载页面 (npm与Node捆绑在一起)。
The third point can be achieved by running the following from your terminal:
第三点可以通过从终端运行以下命令来实现:
npm install http-server -gIf you find yourself needing a sudo prefix (-nix systems) or an elevated command prompt to perform this global installation, you should consider changing the location of global packages.
如果发现需要sudo前缀(-nix系统)或提升的命令提示符来执行此全局安装,则应考虑更改全局软件包的位置 。
Once these requirements are met we can put the following three files in a new folder:
满足这些要求后,我们可以将以下三个文件放入新文件夹中:
example.js is the JavaScript file to request the data.
example.js是用于请求数据JavaScript文件。
example.json is the example JSON file to represent our object.
example.json是代表我们的对象的示例JSON文件。
index.html is the HTML page to call the JavaScript and display the data.
index.html是用于调用JavaScript并显示数据HTML页面。
From the command prompt we can simply invoke http-server within the new folder. Now http://localhost:8080 should be running the demo.
在命令提示符下,我们可以简单地在新文件夹中调用http-server 。 现在http:// localhost:8080应该正在运行演示。
The following code is the complete client-side logic. It waits for the DOMContentLoaded loaded event before attaching an event handler to the click event of the element with the ID get-data. When this element is clicked we attempt to load the JSON from the server using $.getJSON(), before processing the response and displaying it on the screen.
以下代码是完整的客户端逻辑。 在将事件处理程序附加到ID为get-data的元素的click事件之前,它将等待DOMContentLoaded加载事件。 单击此元素后,我们尝试使用$.getJSON()从服务器加载JSON,然后再处理响应并将其显示在屏幕上。
$(document).ready(function () { $('#get-data').click(function () { var showData = $('#show-data'); $.getJSON('example.json', function (data) { console.log(data); var items = data.items.map(function (item) { return item.key + ': ' + item.value; }); showData.empty(); if (items.length) { var content = '<li>' + items.join('</li><li>') + '</li>'; var list = $('<ul />').html(content); showData.append(list); } }); showData.text('Loading the JSON file.'); }); });Besides converting parts of the object to an unordered list, the full object is also printed in the browser’s debugging console. The output is generated in the <div> element with the ID show-data. Even though the element is being reset for every request, we only fill it if the resulting JSON object contains any items at all. Of course, for our example the data is fixed, however, in general any kind of response is possible.
除了将对象的某些部分转换为无序列表之外,完整的对象还被打印在浏览器的调试控制台中。 输出在ID为show-data的<div>元素中生成。 即使为每个请求都重置了元素,我们也仅在生成的JSON对象完全包含任何项目的情况下才填充它。 当然,对于我们的示例,数据是固定的,但是,通常任何形式的响应都是可能的。
Note that we also set some text for the output <div>. If we insert some (artificial) delay for the JSON retrieval, we will see that this actually executes before any result of the $.getJSON request is displayed. The reason is simple: By default $.getJSON is non-blocking, i.e., async. Therefore, the callback will be executed at some (unknown) later point in time.
请注意,我们还为输出<div>设置了一些文本。 如果我们为JSON检索插入一些(人为的)延迟,我们将看到它实际上在显示$.getJSON请求的任何结果之前执行。 原因很简单:默认情况下, $.getJSON是非阻塞的,即异步的。 因此,回调将在某个(未知)稍后的时间点执行。
Distilling the source to obtain the crucial information yields the following block:
提取源以获取关键信息将产生以下框:
$('#get-data').click(function () { $.getJSON('example.json', function (data) { console.log(data); }); });Here we only wire the link to trigger the start of the $.getJSON helper before printing the returned object in the debugging console.
在这里,我们只连接链接以触发$.getJSON帮助程序的启动,然后在调试控制台中打印返回的对象。
The sample JSON file is much larger than the subset we care about. Nevertheless, the sample has been constructed in such a way, to show most of the JSON grammar. The file reads:
样本JSON文件比我们关注的子集大得多。 尽管如此,样本还是以这种方式构造的,以显示大多数JSON语法。 该文件显示为:
{ "items": [ { "key": "First", "value": 100 },{ "key": "Second", "value": false },{ "key": "Last", "value": "Mixed" } ], "obj": { "number": 1.2345e-6, "enabled": true }, "message": "Strings have to be in double-quotes." }In the sample JavaScript, we are only using the array associated with the items key. In contrast to ordinary JavaScript, JSON requires us to place keys in double-quotes. Additionally, we cannot use trailing commas for specifying objects or arrays. However, as with ordinary JavaScript arrays, we are allowed to insert objects of different types.
在示例JavaScript中,我们仅使用与items键关联的数组。 与普通JavaScript相比,JSON要求我们将键放在双引号中。 此外,我们不能使用尾部逗号来指定对象或数组。 然而,与普通JavaScript数组,我们被允许插入不同类型的对象。
We already looked at the script and the sample JSON file. All that’s left is the webpage which provides the parts being used by the JavaScript file to trigger and display the JSON file.
我们已经查看了脚本和示例JSON文件。 剩下的就是该网页,其中提供了JavaScript文件用来触发和显示JSON文件的部分。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Request JSON Test</title> </head> <body> <a href="#" id="get-data">Get JSON data</a> <div id="show-data"></div> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="example.js"></script> </body> </html>There is not much to say here. We use the minified version of jQuery (the old version 1.9.1, which is certainly sufficient for our purposes) from the official webpage. Then we include our script, which is responsible for injecting the logic.
这里没有太多要说的。 我们从官方网页上使用了jQuery的缩小版本(旧版本1.9.1,足以满足我们的目的)。 然后,我们包含脚本,该脚本负责注入逻辑。
Note: As we are including our JavaScript files in the correct place (just before the closing </body> tag), it no longer becomes necessary to use a $(document).ready() callback, because at this point, the document will be ready by definition.
注意 :由于我们将JavaScript文件包含在正确的位置(在</body>标记之前),因此不再需要使用$(document).ready()回调,因为在这一点上,该文档按照定义将准备就绪。
And this is what we end up with.
这就是我们最终得到的结果。
As already mentioned, the $.ajax method is the real deal for any (not only JSON related) web request. This method allows us to explicitly set all the options we care about. We can adjust async to true if we want this to call to run concurrently, i.e., the run potentially at the same time as other code. Setting it to false will prevent other code from running while the download is in progress.
如前所述, $.ajax方法是任何(不仅是与JSON相关的)Web请求的真正保证。 这种方法使我们可以显式设置我们关心的所有选项。 如果我们希望async调用并发运行,即可以与其他代码同时运行,则可以将async调整为true 。 将其设置为false将阻止在下载过程中运行其他代码。
$.ajax({ type: 'GET', url: filename, data: data, async: false, beforeSend: function (xhr) { if (xhr && xhr.overrideMimeType) { xhr.overrideMimeType('application/json;charset=utf-8'); } }, dataType: 'json', success: function (data) { //Do stuff with the JSON data } });The overrideMimeType method (which overrides the MIME type returned by the server) is only called for demonstration purposes. Generally, jQuery is smart enough to adjust the MIME-type according to the used data type.
仅出于演示目的而调用overrideMimeType方法(该方法将覆盖服务器返回的MIME类型)。 通常,jQuery很聪明,可以根据所使用的数据类型来调整MIME类型。
Before we go on to introduce the concept of JSON validation let’s have short look at a more realistic example. Usually, we will not request a static JSON file, but will load JSON which is generated dynamically (for example as the result of calling an API). The JSON generation is dependent on some parameter(s), which have to be supplied beforehand.
在继续介绍JSON验证的概念之前,让我们简短地看一个更现实的示例。 通常,我们不会请求静态JSON文件,而是会加载动态生成的JSON(例如,调用API的结果)。 JSON的生成取决于某些参数,这些参数必须事先提供。
var url = 'https://api.github.com/v1/...'; var data = { q: 'search', text: 'my text' }; $.getJSON(url, data, function (data, status) { if (status === 200) { //Do stuff with the JSON data } });Here we check the status to ensure that the result is indeed the object returned from a successful request and not some object containing an error message. The exact status code is API-dependent, however, for most GET requests a status code of 200 is usual.
在这里,我们检查状态以确保结果确实是成功请求返回的对象,而不是包含错误消息的某些对象。 确切的状态码取决于API,但是,对于大多数GET请求,通常的状态码为200。
The data is supplied in the form of an object, which leaves the task of creating the query string (or transmitting the request body) up to jQuery. This is the best and most reliable option.
数据以对象的形式提供,这使得创建查询字符串(或传输请求主体)的任务交给jQuery。 这是最好和最可靠的选择。
We should not forget to validate our JSON data! There is an online JSON Validator tool called JSONLint, which can be used to validate JSON files. Unlike JavaScript, JSON is very strict and does not have tolerances, e.g. the aforementioned trailing commas or multiple ways of writing keys (with /, without quotes).
我们不应该忘记验证JSON数据! 有一个名为JSONLint的在线JSON验证程序工具 ,可用于验证JSON文件。 与JavaScript不同,JSON非常严格并且没有公差,例如,前面提到的结尾逗号或多种编写键的方式(带/ ,不带引号)。
So, let’s discuss some of the most common errors when dealing with JSON.
因此,让我们讨论一些处理JSON时最常见的错误。
Silent failures on $.getJSON calls: This might happen if, e.g., jsoncallback=json1234 has been used, while the function json1234() does not exist. In such cases the $.getJSON will silently error. We should therefore always use jsoncallback=? to let jQuery automatically handle the initial callback.
$.getJSON调用上的静默故障:如果使用了jsoncallback=json1234 ,而函数json1234()不存在,则可能会发生这种情况。 在这种情况下, $.getJSON将无提示错误。 因此,我们应该始终使用jsoncallback=? 让jQuery自动处理初始回调。
In the best case real JSON (instead of JSONP) is used (either by talking with our own server or via CORS). This eliminates a set of errors potentially introduced by using JSONP. The crucial question is: Does the server / API support JSONP? Are there any restrictions on using JSONP?
在最好的情况下,使用真实的JSON(而不是JSONP )(通过与我们自己的服务器通信或通过CORS进行通信)。 这消除了使用JSONP可能引入的一组错误。 关键问题是:服务器/ API是否支持JSONP? 使用JSONP有任何限制吗?
Uncaught syntax error: Unexpected token (in Chrome) or invalid label (in Firefox). The latter can be fixed by passing the JSON data to the JavaScript callback. In general, however, this is a strong indicator that the JSON is malformed. Consider using JSONLint as advised above.
Uncaught syntax error: Unexpected token (在Chrome中)或invalid label (在Firefox中)。 后者可以通过将JSON数据传递给JavaScript回调进行修复。 但是,通常,这是JSON格式错误的有力指示。 考虑按照上面的建议使用JSONLint 。
The big question is now: How do we detect if the error actually lies in the transported JSON?
现在最大的问题是:我们如何检测错误是否真正在于传输的JSON中?
There are three essential points that should be covered before starting any JSON-related debugging:
开始任何与JSON相关的调试之前,应涵盖三个基本要点:
We have to make sure that the JSON returned by the server is in the correct format with the correct MIME-type being used. 我们必须确保服务器返回的JSON格式正确,并使用了正确的MIME类型。We can try to use $.get instead of $.getJSON as it might be that our server returns invalid JSON. Also if JSON.parse() fails on the returned text we immediately know that the JSON is to blame.
我们可以尝试使用$ .get而不是$.getJSON因为这可能是我们的服务器返回了无效的JSON。 同样,如果JSON.parse()在返回的文本上失败,我们会立即知道应该归咎于JSON。
We can check the data that is being returned by logging it to the console. This should then be the input for further investigations. 我们可以通过将其记录到控制台来检查返回的数据。 然后,应将其作为进一步调查的输入。Debugging should then commence with the previously mentioned JSONLint tool.
然后,调试应从前面提到的JSONLint工具开始。
JSON is the de-facto standard format for exchanging text data. jQuery’s $.getJSON() method gives us a nice little helper to deal with almost any scenario involving a request for JSON formatted data. In this article we investigated some methods and possiblities that come with this handy helper.
JSON是用于交换文本数据的事实上的标准格式。 jQuery的$.getJSON()方法为我们提供了一个很好的小助手,可以处理几乎所有涉及JSON格式数据请求的情况。 在本文中,我们研究了此便捷助手所附带的一些方法和可能性。
Are there any other best practices for $.getJSON() you cannot live without?
对于$.getJSON()还有其他最佳实践吗?
翻译自: https://www.sitepoint.com/ajaxjquery-getjson-simple-example/