JSON 简介
JSON: JavaScript Object Notation(JavaScript 对象标记法)。
JSON 是一种存储和交换数据的语法。
JSON 是通过 JavaScript 对象标记法书写的文本。
当数据在浏览器与服务器之间进行交换时,这些数据只能是文本
JSON 用于存储和传输数据的格式。
JSON 是文本,文本可以在任何地方传输,并可通过任何编程语言读取。
JavaScript 对象可以转换为 JSON,JSON 可以转换回 JavaScript 对象
发送数据
如果您的数据存储在 JavaScript 对象中,您可以把该对象转换为 JSON,然后将其发送到服务器。
实例
var myObj = { name:“Bill Gates”, age:62, city:“Seattle” };
var myJSON = JSON.stringify(myObj);
window.location = “demo_json.php?x=” + myJSON;
接收数据
如果您以 JSON 格式接收到数据,您能够将其转换为 JavaScript 对象:
实例
var myJSON = ‘{ “name”:“Bill Gates”, “age”:62, “city”:“Seattle” }’;
var myObj = JSON.parse(myJSON);
document.getElementById(“demo”).innerHTML = myObj.name;
存储数据
在存储数据时,数据必须是某种具体的格式,并且无论您选择在何处存储它,文本永远是合法格式之一。
JSON 让 JavaScript 对象存储为文本成为可能。
实例:把数据存储在本地存储中
//存储数据:
myObj = { name:"Bill Gates", age:62, city:"Seattle" };
myJSON = JSON.stringify(myObj);
localStorage.setItem("testJSON", myJSON);
//接收数据:
text = localStorage.getItem("testJSON");
obj = JSON.parse(text);
document.getElementById("demo").innerHTML = obj.name;
JSON 使用 JavaScript 语法,但是 JSON 格式是纯文本的。文本可被任何编程语言作为数据来读取和使用。
为 JSON 格式仅仅是文本,它能够轻松地在服务器浏览器之间传输,并用作任何编程语言的数据格式。
JavaScript 提供內建函数把以 JSON 格式写的字符串转换为原生 JavaScript 对象
JSON 语法
JSON 数据- 名称和值1
JSON 数据写为名称/值对。
名称/值由字段名称构成,后跟冒号和值
"name":"Bill Gates"
JSON 语法是 JavaScript 语法的子集。JSON 名称需要双引号,而 JavaScript 名称不需要
在 JSON 中,键必须是字符串,由双引号包围
JSON{ "name":"Bill Gates" }
JavaScript{ name:"Bill Gates" }
在 JavaScript 中,键可以是字符串、数字或标识符名称
JSON 值
在 JSON 中,值必须是以下数据类型之一:
- 字符串
数字
对象(JSON 对象)
数组
布尔
null
在 JavaScript 中,以上所列均可为值,外加其他有效的 JavaScript 表达式,包括:
-
函数
日期
undefined -
JSON 文件的文件类型是 “.json”
JSON 文本的 MIME 类型是 “application/json”
JSON vs XML
JSON 和 XML 均可用于从 web 服务器接收数据。
JSON 实例
{"employees":[
{ "firstName":"Bill", "lastName":"Gates" },
{ "firstName":"Steve", "lastName":"Jobs" },
{ "firstName":"Elon", "lastName":"Musk" }
]}
XML 实例
<employees>
<employee>
<firstName>Bill</firstName>
<lastName>Gates</lastName>
</employee>
<employee>
<firstName>Steve</firstName>
<lastName>Jobs</lastName>
</employee>
<employee>
<firstName>Elon</firstName>
<lastName>Musk</lastName>
</employee>
</employees>
JSON 类似 XML,因为:
JSON 和 XML 都是“自描述的”(人类可读的)
JSON 和 XML 都是分级的(值中有值)
JSON 和 XML 都能被大量编程语言解析和使用
JSON 和 XML 都能被 XMLHttpRequest 读取
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.parse()解析
请想象一下我们从 web 服务器接收到这段文本:
'{ "name":"Bill Gates", "age":62, "city":"Seattle"}'
请使用 JavaScript 函数 JSON.parse() 把文本转换为 JavaScript 对象:
var obj = JSON.parse('{ "name":"Bill Gates", "age":62, "city":"Seattle"}');
<p id="demo"></p>
<script>
var text = '{"employees":[' +
'{"firstName":"Bill","lastName":"Gates" },' +
'{"firstName":"Steve","lastName":"Jobs" },' +
'{"firstName":"Elon","lastName":"Musk" }]}';
obj = JSON.parse(text);
document.getElementById("demo").innerHTML =
obj.employees[1].firstName + " " + obj.employees[1].lastName;
</script>
使用 XMLHttpRequest 从服务器获取数据
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 是数组:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myArr = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myArr[0];
}
};
xmlhttp.open("GET", "json_demo_array.txt", true);
xmlhttp.send();
把字符串转换为日期:
var text = '{ "name":"Bill Gates", "birth":"1955-10-28", "city":"Seattle"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);
document.getElementById("demo").innerHTML = obj.name + ", " + obj.birth;
将字符串转换为日期,使用 reviver 函数:
var text = '{ "name":"Bill Gates", "birth":"1955-10-28", "city":"Seattle"}';
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;
把字符串转换为函数:
var text = '{ "name":"Bill Gates", "age":"function () {return 62;}", "city":"Seattle"}';
var obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");
document.getElementById("demo").innerHTML = obj.name + ", " + obj.age();
应该避免在 JSON 中使用函数,函数会丢失它们的作用域,而且您还需要使用 eval() 把它们转换回函数
JSON.stringify()字符串化
JSON 的常规用途是同 web 服务器进行数据交换。
在向 web 服务器发送数据时,数据必须是字符串。
通过 JSON.stringify() 把 JavaScript 对象转换为字符串。(json)
对 JavaScript 对象进行字符串化
<script>
var obj = { name: "Bill", age: 62, city: "Seatle" };
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
</script>
//返回{"name":"Bill","age":62,"city":"Seatle"}
Stringify JavaScript 数组
var arr = [ "Bill Gates", "Steve Jobs", "Elon Musk" ];
var myJSON = JSON.stringify(arr);
document.getElementById("demo").innerHTML = myJSON;
在 JSON 中,不允许日期对象。JSON.stringify() 函数将把任何日期转换为字符串。
var obj = { "name":"Bill Gates", "today":new Date(), "city":"Seattle"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
在 JSON 中,不允许函数作为对象值。
JSON.stringify() 函数将从 JavaScript 对象删除任何函数,包括键和值:
var obj = { "name":"Bill Gates", "age":function () {return 62;}, "city":"Seattle"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
如果您在运行 JSON.stringify() 函数前已将函数转换为字符串,这个环节可以省略。
var obj = { "name":"Bill Gates", "age":function () {return 62;}, "city":"Seattle"};
obj.age = obj.age.toString();
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON;
应该避免在 JSON 中使用函数,函数会失去其作用域,而且您还需要使用 eval() 将它们转换回函数。
JSON 对象
{ "name":"Bill Gates", "age":62, "car":null }
JSON 对象被花括号 {} 包围。
JSON 对象以键/值对书写。
键必须是字符串,值必须是有效的 JSON 数据类型(字符串、数字、对象、数组、布尔或 null)。
键和值由冒号分隔。
每个键/值对由逗号分隔。
可以通过使用点号(.
)来访问对象值x = myObj.name;
您也可以使用方括号([ ]
)来访问对象值x = myObj["name"];
遍历对象
使用 for-in 遍历对象属性:
var myObj, x;
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 对象
myObj = {
"name":"Bill Gates",
"age":62,
"cars": {
"car1":"Porsche",
"car2":"BMW",
"car3":"Volvo"
}
}
修改值
myObj.cars.car3 = "Mercedes Benz";
|| myObj.cars["car3"] = "Mercedes Benz";
使用 delete 关键词来删除 JSON 对象的属性
JSON 数组
JSON 对象中的数组
数组可以是对象属性的值:
{
"name":"Bill Gates",
"age":62,
"cars":[ "Porsche", "BMW", "Volvo" ]
}
遍历数组
通过使用 for-in 循环来访问数组值:
for (i in myObj.cars) { x += myObj.cars[i]; }
使用 for 循环:
for (i = 0; i < myObj.cars.length; i++) { x += myObj.cars[i]; }
JSON 对象中的嵌套数组
数组中的值也可以另一个数组,或者甚至另一个 JSON 对象:
myObj = {
"name":"Bill Gates",
"age":62,
"cars": [
{ "name":"Porsche", "models":[ "911", "Taycan" ] },
{ "name":"BMW", "models":[ "M5", "M3", "X5" ] },
{ "name":"Volvo", "models":[ "XC60", "V60" ] }
]
}
遍历数组内的数组
<p id="demo"></p>
<script>
var myObj, i, j, x = "";
myObj = {
"name":"Bill Gates",
"age":62,
"cars": [
{"name":"Porsche", "models":["911", "Taycan"]},
{"name":"BMW", "models":["M5", "M3", "X5"]},
{"name":"Volvo", "models":["XC90", "V60"] }
]
}
for (i in myObj.cars) {
x += "<h2>" + myObj.cars[i].name + "</h2>";
for (j in myObj.cars[i].models) {
x += myObj.cars[i].models[j] + "<br>";
}
}
document.getElementById("demo").innerHTML = x;
</script>
修改数组值
myObj.cars[1] = "Mercedes Benz";
使用 delete 关键词来删除数组中的项目
JSON PHP
通过使用 PHP 函数 json_encode(),PHP 中的对象可转换为 JSON:
<?php
$ myObj->name = "Bill Gates";
$ myObj->age = 62;
$ myObj->city = "Seattle";
$ myJSON = json_encode($myObj);
echo $myJSON;
?>
从服务器上的 PHP 获取 JSON 数据
<p id="demo"></p>
<script>
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", "/demo/demo_php_json_encode.php", true);
xmlhttp.send();
</script>
在使用 PHP 函数 json_encode() 时,PHP 中的数组也将被转换为 JSON:
<?php
$myArr = array("Bill Gates", "Steve Jobs", "Elon Musk");
$myJSON = json_encode($myArr);
echo $myJSON;
?>
PHP 是服务器端编程语言,应该用于只能由服务器执行的操作
obj = { "table":"customers", "limit":10 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "demo_json_db.php?x=" + dbParam, true);
xmlhttp.send();
例子解释:
- 定义包含 table 属性和 limit 属性的对象。
- 将这个对象转换为 JSON 字符串。
- 向这个 PHP 文件发送请求,其中 JSON 作为参数。
- 等待直到请求返回结果(作为 JSON)。
- 显示从 PHP 文件接收到的结果。
<?php
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_GET["x"], false);
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT name FROM ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($outp);
?>
PHP 文件解释:
- 将请求转换为对象,使用 PHP 函数 json_decode()。
- 访问数据库,用所请求的数据填充数组。
- 把数组添加到对象,使用 json_encode() 函数以 JSON 返回该对象。
遍历结果
把从 PHP 文件接收到的结果转换为 JavaScript 对象,或者是在本例中的,一个 JavaScript数组:使用 JSON.parse() 把 JSON 转换为 JavaScript 对象:
<script>
var xmlhttp, myObj, x, txt = "";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
for (x in myObj) {
txt += myObj[x].CustomerId + "<br>";
}
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("GET", "/demo/demo_json_db.php", true);
xmlhttp.send();
</script>
PHP 方法 = POST
在向服务器发送数据时,通常最好是使用 HTTP POST 方法。
如需使用 POST 方法来发送 AJAX 请求,请指定该方法和正确的头部。
发送到服务器的数据现在必须是 .send() 方法的参数:
实例
obj = { "table":"customers", "limit":10 };
dbParam = JSON.stringify(obj); //var xmlhttp, myObj, x, txt = "";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
for (x in myObj) {
txt += myObj[x].name + "<br>";
}
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("POST", "demo_json_db.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
PHP 文件
使用 $_POST
而不是 $_GET
:
<?php
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_POST["x"], false);
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT name FROM ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($outp);
?>
JSON HTML
JSON 非常易于转译为 JavaScript。JavaScript 可用于在网页中生成 HTML
使用作为 JSON 接收到的数据来生成表格:
实例
obj = { "table":"customers", "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
txt += "</table>"
document.getElementById("demo").innerHTML = txt;
}
}
xmlhttp.open("POST", "json_demo_db_post.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
动态 HTML 表格
<select id="myselect" onchange="change_myselect(this.value)">
<option value="">Choose an option:</option>
<option value="customers">Customers</option>
<option value="products">Products</option>
<option value="suppliers">Suppliers</option>
</select>
<script>
function change_myselect(sel) {
var obj, dbParam, xmlhttp, myObj, x, txt = "";
obj = { "table":sel, "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<table border='1'>"
for (x in myObj) {
txt += "<tr><td>" + myObj[x].name + "</td></tr>";
}
txt += "</table>"
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("POST", "json_demo_db_post.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
}
</script>
HTML 下拉列表
用接收到的 JSON 数据来生成 HTML 下拉列表:
实例
obj = { "table":"customers", "limit":20 };
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
txt += "<select>"
for (x in myObj) {
txt += "<option>" + myObj[x].name;
}
txt += "</select>"
document.getElementById("demo").innerHTML = txt;
}
}
xmlhttp.open("POST", "json_demo_db_post.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
JSONP(无需考虑跨域问题)
JSONP 是一种无需考虑跨域问题即可传送 JSON 数据的方法。
JSONP 不使用 XMLHttpRequest 对象。
JSONP 使用
<?php
$myJSON = '{ "name":"Bill Gates", "age":62, "city":"Seattle" }';
echo "myFunc(".$myJSON.");";
?>
结果返回对名为 “myFunc” 的函数的调用,其中的 JSON 数据为参数。
请确保客户端存在该函数。
函数 “myFunc” 位于客户端,用于处理 JSON 数据:
function myFunc(myObj) {
document.getElementById("demo").innerHTML = myObj.name;
}
在按钮被点击时创建和插入
function clickButton() {
var s = document.createElement("script");
s.src = "demo_jsonp.php";
document.body.appendChild(s);
}
动态 JSONP 结果
上例仍然是静态的。
可通过向 PHP 文件发送 JSON 来创建动态的例子,然后根据这个 php 文件获得的信息让它返回一个 JSON 对象。
PHP 文件
<?php
header("Content-Type: application/json; charset=UTF-8");
$obj = json_decode($_GET["x"], false);
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT name FROM ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo "myFunc(".json_encode($outp).")";
?>
PHP 文件解释:
- 把请求转换为对象,使用 PHP 函数 json_decode()。
- 访问数据库,并用被请求的数据填充数组。
- 向对象添加数组。
- 使用 json_decode() 函数把该数组转换为 JSON。
- 用 “myFunc()” 封装返回对象。
JavaScript 实例
将从 php 文件调用 “myFunc” 函数:
function clickButton() {
var obj, s
obj = { "table":"products", "limit":10 };
s = document.createElement("script");
s.src = "jsonp_demo_db.php?x=" + JSON.stringify(obj);
document.body.appendChild(s);
}
function myFunc(myObj) {
var x, txt = "";
for (x in myObj) {
txt += myObj[x].name + "<br>";
}
document.getElementById("demo").innerHTML = txt;
}
回调函数
如果无法控制服务器文件,那么如何使服务器文件调用正确的函数呢?
有时服务器文件提供回调函数作为参数:
实例
PHP 文件会调用您作为回调参数传递的函数:
function clickButton() {
var s = document.createElement("script");
s.src = "jsonp_demo_db.php?callback=myDisplayFunction";
document.body.appendChild(s);
}
在计算机科学中,名值对,也可以称为键值对或属性值对,是一种基本的数据表示在计算系统和应用程序中。设计人员通常希望开放式的数据结构,可以在未修改现有的代码或数据的情况下进行未来扩展。在这种情况下,数据模型的全部或部分可以表示为元组的集合< name,value >;每个元素都是名值对,根据特定应用程序和程序员选择的实现。 ↩︎