{
"person": {
"name": "Lindsay Bassett",
"heightInInches": 66,
"head": {
"hair": {
"color": "light blond",
"length": "short",
"style": "A-line"
},
"eyes": "green"
}
}
}
JSON Schema 校验数据
JSON Schema数据交换中的一种虚拟合同,负责提供一致性验证。是负责数据接收第一道防线,也是数据发送方节约时间,保证数据正确的好工具
JSON Schema在第一个键值对中声明$schema,并给定校验的地址。 第二个键值对为JSON Schema的标题,第三个就是我们要定义的一些属性了。下面是一个猫的schema文件。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Cat",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number",
"description": "Your cat's age in years."
},
"declawed": {
"type": "boolean"
}
}
}
JSON Schema可以解决下列一致性验证的问题
- 1.值的数据类型是否正确? 可以具体规定一个值是数字、字符串等类型。
- 2.是否包含所需要的数据? 可以具体规定哪些数据是需要的,哪些不需要的。
- 3.值的形式是不是我需要的? 可以指定范围,最小值最大值。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Cat",
"properties": {
"name": {
"type": "string",
"minLength": 3,
"maxLength": 20
},
"age": {
"type": "number",
"description": "Your cat's age in years.",
"minimum": 0
},
"declawed": {
"type": "boolean"
},
"description": {
"type": "string"
}
},
"required": [
"name",
"age",
"declawed"
]
}
通过对属性字段进行约束来达到对数据的约束,同时还可以通过required属性来确定需要的数据,以及确定数据格式。
JSON与web安全
常见的web安全有跨站请求伪造CSRF,和脚本注入XSS。跨站请求伪造(CSRF),指利用站点对用户浏览器的信任进行攻击。注入攻击依赖于将数据注入到web应用程序以方便恶意数据执行或编译的攻击。
JSON本身不构成什么威胁,它只是文本。
在定位JSON安全问题时,应该记住以下3件事.
1.不要使用顶级数组,顶级数组是合法的JavaScript脚本,他们可以用<script>
标签链接并使用。
[
{
"user": "bobbarker"
},
{
"phone": "555-555-5555"
}
]
上面的json格式是合法的,但是这种合法的json格式比较危险,叫做顶层的json数组。因为网站一般会利用存在cookies或者session中的信息进行验证当前用户是否属于合法信息。
<script src="https://www.yourspecialbank.com/user.json"></script>
通过广告或者色情图片的链接,诱导用户去点击,这就使得user.json数据被黑客给窃取了。
所以可以通过将数组放在对象中,编程非法的JavaScript,这样就避免了script的加载。
{
"info": [
{
"user": "bobbarker"
},
{
"phone": "555-555-5555"
}
]
}
这只是一个实例,CSRF实际上就是通过登录网址的登录态,在还没退出之前通过这一信任凭证,诱导你点击一个危险的script标签,
当黑客知道了银行站点存储json数据的url地址后,会把它放在一个scritp标签中,通过script标签来绕开同源策略,由于顶层JSON数组是合法的JavaScript代码,它就可以得到我们的数据。
2.对于不想公开的资源,仅允许使用HTTPPost方法请求,而不是Get方法,get方法可以通过url请求,甚至放在script标签中。
另外一个就是XSS攻击,这更多了,这是因为JavaScript的eval()函数会将传入的字符串无差异化的编译执行,这就使得一些人利用这一漏洞,在里面执行一个JavaScript脚本。比如利用一些不那么规矩的JSON,虽然合法,但是有很大的漏洞。
{
"message": "<div onmouseover=\"alert('gotcha!')\">hover here.</div>"
}
3.使用JSON.parser()来替代eval(),eval()函数会将传入的字符串编译并执行,
var jsonString = "alert('this is bad')";
var myObject = eval("(" + jsonString + ")");
alert(myObject.animal);
这会让你的代码易被攻击,应仅使用JSON.parser()来解析json数据。
var jsonString = '{"animal":"cat"}';
var myObject = JSON.parse(jsonString);
alert(myObject.animal);
安全漏洞通常由于开发人员没有考虑“黑客如何利用这一点”这一问题所导致的。
JSON与XMLHTTPRequest
XMLHTTPRequest并不仅限于XML,还可以用它来请求JSON资源
正常的建立一个ajax过程的连接是
var myXMLHttpRequest = new XMLHttpRequest();
var url = "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139";
myXMLHttpRequest.onreadystatechange = function() {
if (myXMLHttpRequest.readyState === 4 && myXMLHttpRequest.status === 200) {
//JSON的反序列化
var myObject = JSON.parse(myXMLHttpRequest.responseText);
// 对象序列化
var myJSON = JSON.stringify(myObject);
// let's display this in the div with the id "json"
document.getElementById("json").innerHTML = myJSON;
}
else if (myXMLHttpRequest.readyState === 4 && myXMLHttpRequest.status !== 200)
{
// fail.
}
}
myXMLHttpRequest.open("GET", url, true);
myXMLHttpRequest.send();
序列化是指将对象转化为文本的操作,反序列化是指将文本转化为对象的操作。
跨域的问题,可以通过CORS通过服务端设置
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:GET, POST
Access-Control-Allow-Origin:\*
通过哪些允许哪些HTTP方法,哪些域名下的js文件的共享。
通过JSONP动态插入script标签,并添加到html文档中,这样就可以不受同源策略的影响了。并通过queryString问号后面的参数来告诉服务器是哪个回调函数。
<script>
function getTheAnimal(data) {
var myAnimal = data.animal;
alert(myAnimal);
}
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "example.json?callback=doSomething";
document.getElementsByTagName('head')[0].appendChild(script);
</script>
通过JSONP动态命名函数:
doSomething({
"animal": "cat"
});
JSON与客户端框架
1.JSON与Jquery
- Jquery.parserJSON()
Jqury是专注于操作DOM的第三方类库,同时对JSON的处理也进行了改进,这样不仅让我们在实现相同功能的时候减少了代码量的输出,更多的还做了浏览器兼容性的处理。比如前面提到的JSON.sparse(),jQuery也有自己的JQuery.parseJSON函数。
var myAnimal = JSON.parse('{ "animal" : "cat" }');
var myAnimal = jQuery.parseJSON('{ "animal" : "cat" }');
通过阅读源码,可以发现一个jquery的函数,它不仅调用JSON.parser()函数,还会兼容那些不支持JSON.parser()函数的老式浏览器,且通过验证字符来评估字符串,从而避免了可能的安全问题。
- jquery.getJSON()
在发送HTTP请求上,jQuery也为我们做了很多。jquery.ajax()函数的简写形式,其中包含了将json解析为JavaScript对象的功能。
原来发送一个Ajax请求
<script>
var myXMLHttpRequest = new XMLHttpRequest();
var url = "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139";
myXMLHttpRequest.onreadystatechange = function() {
if (myXMLHttpRequest.readyState === 4 && myXMLHttpRequest.status === 200) {
var myObject = JSON.parse(myXMLHttpRequest.responseText);
var description = "It's " + myObject.weather[0].description + " and " + myObject.main.temp + " degrees in " + myObject.name + ".";
document.getElementById("weather").innerHTML = description;
var myJSON = JSON.stringify(myObject);
document.getElementById("json").innerHTML = myJSON;
}
else if (myXMLHttpRequest.readyState === 4 && myXMLHttpRequest.status !== 200)
{
// fail.
document.getElementById("weather").innerHTML = "failed.";
document.getElementById("json").innerHTML = "failed.";
document.getElementById("error").innerHTML = "Unable to connect to the open weather map API."
}
}
myXMLHttpRequest.open("GET", url, true);
myXMLHttpRequest.send();
</script>
通过jQuery的封装
<script>
var myXMLHttpRequest = new XMLHttpRequest();
var url = "http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139";
$.getJSON(url, function(data) {
var description = "It's " + data.weather[0].description + " and " + data.main.temp + " degrees in " + data.name + ".";
document.getElementById("weather").innerHTML = description;
// The object serialized
var myJSON = JSON.stringify(data);
// let's display this in the div with the id "json"
document.getElementById("json").innerHTML = myJSON;
})
.error(function() {
document.getElementById("weather").innerHTML = "failed.";
document.getElementById("json").innerHTML = "failed.";
document.getElementById("error").innerHTML = "Unable to connect to the open weather map API."
});
</script>
2. Angular与JSON
angular是一个MVVM型框架,以数据驱动。它通过$http来请求数据,这样使得看起来更为简洁。只需要简单的几行就能搞定。
angular.module('myApp', []).controller('myAppController', function($scope, $http) {
$http.get('http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139').success(function(data, status, headers, config) {
$scope.weatherData = data;
});
});
服务端的JSON
JSON作为一种数据交换格式,要在web端使用,必须得到客户端与服务器端的致辞。
客户端:HTML+CSS+Javascript
服务端:PHP,JAVA,Node,.NET, RuBy,Go….
PHP 与 JSON
PHP是用于创建动态web页面的服务端脚本语言。
- 序列化
在PHP中,可以通过内置的JSON支持快速的将PHP对象序列化。通过json_encode()函数将PHP对象序列化为一个JSON。
创建一个Address对象。
<?php
class Account {
public $firstName;
public $lastName;
public $phone;
public $gender;
public $addresses;
public $famous;
}
class Address {
public $street;
public $city;
public $state;
public $zip;
}
$address1 = new Address();
$address1->street = "123 fakey st";
$address1->city = "Somewhere";
$address1->state = "CA";
$address1->zip = 96027;
$address2 = new Address();
$address2->street = "456 fake dr";
$address2->city = "Some Place";
$address2->state = "CA";
$address2->zip = 96345;
$account = new Account();
$account->firstName = "Bob";
$account->lastName = "Barker";
$account->gender = "male";
$account->phone = "555-555-5555";
$account->famous = true;
$account->addresses = array($address1, $address2);
$json = json_encode($account);
echo $json;
?>
2.反序列化
PHP中JSON对象可以通过**json_decode()**函数将JSON反序列化为PHP对象,因为PHP对象类型不确定,所以不能一步到位,可以通过循环遍历该对象的属性来进行反序列化。