什么是JSON
JavaScript Object Notation(JavaScript 对象标记法)。
JSON 是一种存储和交换数据的语法。
JSON 是通过 JavaScript 对象标记法书写的文本。
为什么使用JSON
1.当数据在浏览器与服务器之间进行交换时,这些数据只能是文本。
2.JSON 属于文本,并且我们能够把任何 JavaScript 对象转换为 JSON,然后将 JSON 发送到服务器。
3.我们也能把从服务器接收到的任何 JSON 转换为 JavaScript 对象。
4.以这样的方式,我们能够把数据作为 JavaScript 对象来处理,无需复杂的解析和转译。
一、JSON语法以及和JavaScript对象对比
JSON 语法衍生于 JavaScript 对象标记法语法:
- 数据以名称–值对的形式‘存储着’
- 每个数据间由逗号分隔
- 花括号容纳对象{object}
- 方括号容纳数组[…]
区别1:
在 JSON 中,键必须是字符串,由双引号包围:
JSON
{ "name":"Bill Gates" }
在 JavaScript 中,键可以是字符串、数字或标识符名称:
JavaScript
{ name:"Bill Gates" }
区别2:
在 JSON 中,值必须是以下数据类型之一(重要):
- 字符串
- 数字
- 对象(JSON 对象)
- 数组
- 布尔
- null
在 JavaScript 中,以上所列均可为值,外加其他有效的 JavaScript 表达式,包括:
- 函数
- 日期
- undefined
区别3
在 JSON 中,字符串值必须由双引号编写:
{ "name":"Bill Gates" }
在 JavaScript 中,您可以书写使用双引号或单引号的字符串值:
{ name:'Bill Gates' }
JSON 使用 JavaScript 语法
因为 JSON 语法由 JavaScript 对象标记法衍生而来,所以很少需要其他额外的软件来处理 JavaScript 中的 JSON。
通过 JavaScript,您能够创建对象并向其分配数据,就像这样:
实例
var person = { name : "Bill Gates", age : 62, city : "Seattle" };
//我们可以够像这样访问 JavaScript 对象:
// 返回 Bill Gates
person.name;
//也可以像这样访问它:
// 返回 Bill Gates
person["name"];
//可以像这样修改数据:
person.name = "Steve Jobs";
也可以像这样修改它:
person["name"] = "Steve Jobs";
二、JSON和XML的区别和优点
- JSON 不使用标签
- JSON 更短
- JSON 的读写速度更快
- JSON 可使用数组
最大的不同在于:
XML 必须使用 XML 解析器进行解析。而 JSON 可通过标准的 JavaScript 函数进行解析。
JSON 相比于 XML 的优点
- XML 比 JSON 更难解析。
- JSON 被解析为可供使用的 JavaScript 对象。
对于 AJAX 应用程序,JSON 比 XML 更快更易用:
使用 XML
- 读取 XML 文档
- 使用 XML DOM 遍历文档
- 提取变量中存储的值
使用 JSON
- 读取 JSON 字符串
- JSON.Parse JSON 字符串
三、JSON解析–JSON.parse()
简介
JSON 的常规用途是同 web 服务器进行数据传输。
在从 web 服务器接收数据时,数据永远是字符串。
通过 JSON.parse() 解析数据,这些数据会成为 JavaScript 对象。
实例
假如我们从 web 服务器接收到这段文本:
'{ "name":"Bill Gates", "age":62, "city":"Seattle"}'
使用 JavaScript 函数 JSON.parse() 把文本转换为 JavaScript 对象:
var obj = JSON.parse('{ "name":"Bill Gates", "age":62, "city":"Seattle"}');
随后,我们就可以使用该JavaScript对象了
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age;
</script>
因此,我们能够通过使用 AJAX 请求从服务器请求 JSON。
只要服务器的响应是用 JSON 格式编写的,我们就可以将字符串解析成 JavaScript 对象。
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open("GET", "json_demo.txt", true);
xmlhttp.send();
前面提到JSON 中不允许日期对象。那有没有别的方式传入日期呢,答案是有的,此时需要揭示JSON.parse()的第二个参数,被称为 reviver。
这个 reviver 参数是函数,在返回值之前,它会检查每个属性。
例子:
将字符串转换为日期,使用 reviver 函数:
var text = '{ "name":"Bill Gates", "birth":"1955-10-28", "city":"Seattle"}';
//第二个参数是 reviver 函数,返回值之前遍历键值对
var obj = JSON.parse(text, function (key, value) {
if (key == "birth") {
return new Date(value);
} else {
return value;
}});
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth;
四、JSON对象
{ "name":"Bill Gates", "age":62, "car":null }
访问对象值
可以通过使用点号(.)来访问对象值或者使用方括号([])来访问对象值。
myObj = { "name":"Bill Gates", "age":62, "car":null };
x = myObj.name;
x = myObj["name"];
遍历对象
使用for-in遍历属性
myObj = { "name":"Bill Gates", "age":62, "car":null };
for (x in myObj) {
document.getElementById("demo").innerHTML += x;
}
使用for-in时需要使用括号标记法访问属性的值
myObj = { "name":"Bill Gates", "age":62, "car":null };
for (x in myObj) {
document.getElementById("demo").innerHTML += myObj[x];
}
嵌套的 JSON 对象
一个 JSON 对象中的值可以是另一个 JSON 对象。
myObj = {
"name":"Bill Gates",
"age":62,
"cars": {
"car1":"Porsche",
"car2":"BMW",
"car3":"Volvo"
}
}
x = myObj.cars.car2;
//或者:
x = myObj.cars["car2"];
myObj.cars.car3 = "Mercedes Benz";
//或者
myObj.cars["car3"] = "Mercedes Benz";
//删除
delete myObj.cars.car1;
六、JSONP
最后说一个在跨域问题里常见的概念JSOP。
- JSONP 是一种无需考虑跨域问题即可传送 JSON 数据的方法。
- JSONP 不使用 XMLHttpRequest 对象。
- JSONP 使用 < script> 标签取而代之。
JSONP 简介
JSONP 指的是 JSON with Padding。
从另一个域请求文件会引起问题,由于跨域政策。
从另一个域请求外部脚本没有这个问题。
JSONP 利用了这个优势,并使用 script 标签替代 XMLHttpRequest 对象。
<script src="demo_jsonp.php">
Server 文件
服务器上的文件在函数调用中封装结果:
<?php
$myJSON = '{ "name":"Bill Gates", "age":62, "city":"Seattle" }';
echo "myFunc(".$myJSON.");";
?>
结果返回对名为 “myFunc” 的函数的调用,其中的 JSON 数据为参数(即$myJSON,用PHP语言定义的JSON数据)。
请确保客户端存在该函数。
JavaScript 函数
函数 “myFunc” 位于客户端,用于处理返回的JSON 数据:
实例
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
完整的例子
<!DOCTYPE html>
<html>
<body>
<h1>点击按钮</h1>
<p>将创建一个带有 src 属性的 script 标签并将其放在文档中。</p>
<p>PHP 文件以 JSON 对象作为参数返回对函数的调用。</p>
<button onclick="clickButton()">单击我!</button>
<p id="demo"></p>
<script>
function clickButton() {
var s = document.createElement("script");
s.src = "/demo/demo_php_jsonp.php";
document.body.appendChild(s);
}
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
</script>
</body>
</html>
创建动态脚本标签
上例会在页面加载时执行 “myFunc” 函数,根据放置脚本标签的位置,这样不很令人满意。
Script 只应该在需要时创建:
在按钮被点击时创建和插入 < script> 标签:
function clickButton() {
var s = document.createElement("script");
s.src = "demo_jsonp.php";
document.body.appendChild(s);
}
回调函数
如果无法控制服务器文件,那么如何使服务器文件调用正确的函数呢?
有时服务器文件提供回调函数作为参数:
PHP 文件会调用物品们作为回调参数传递的函数:
function clickButton() {
var s = document.createElement("script");
//?callback=myDisplayFunction
s.src = "jsonp_demo_db.php?callback=myDisplayFunction";
document.body.appendChild(s);
}
当然jsonp不能完全使用跨域问题,因为只支持GET请求,且只能用于获取 JSON 格式的数据,不安全、也比较老不符合最新的web标准等等。