ajax与json学习

内容概览

  1. ajax的概念及作用

  2. 同步请求与异步请求

  3. ajax的重要对象---XMLHttpRequest对象

  4. $.ajax()的使用

  5. json的概念

  6. json支持的数据类型

  7. json的基本语法

  8. json的解析与序列化

一、ajax的基本认识

什么是ajax

  1. AJAX的全称是Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

  2. ajax不是新的编程语言,而是一种更新部分网页的技术。

  3. ajax可以在不重新加载整个网页的情况下,对网页的某部分进行更新。而传统的网页(不使用ajax)如果需要更新内容,必须重载整个网页面。

ajax的优点

  1. 最大的一点是页面无刷新,用户的体验非常好。

  2. 使用异步方式与服务器通信,具有更加迅速的响应能力。

  3. 可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。

ajax的缺点

  1. ajax不支持浏览器back按钮。

  2. 安全问题 AJAX暴露了与服务器交互的细节。

  3. 对搜索引擎的支持比较弱。

  4. 破坏了程序的异常机制。

  5. 不容易调试

同步方式发送请求

发送一个请求,需要等待响应返回,然后才能够发送下一个请求,如果该请求没有响应,不能发送下一个请求,客户端会处于一直等待过程中。

同步请求:客户端提交请求->等待服务器处理->处理完毕返回 ,这个期间客户端浏览器不能干任何事

异步方式发送请求

发送一个请求,不需要等待响应返回,随时可以再发送下一个请求,即不需要等待。

异步请求: 客户端请求通过事件触发->服务器处理(此时浏览器仍然可以作其他事情)->服务器处理完毕,异步的给予浏览器响应.

ajax的重要对象---XMLHttpRequest对象

向服务器发送请求,毫无疑问需要使用Http协议,也就是我们需要通过JS来向服务器发送一个请求报文。

这里我们来回顾一下请求报文的格式:

请求首行
请求头
空行
请求体

XMLHttpRequest对象的由来:

​ 这是一个请求报文的格式,那我们如果手动的创建这么一个报文格式来发送给服务器想必是非常麻烦呢,于是浏览器为我们提供了一个XMLHttpRequest对象。

XMLHttpRequest的作用

  1. XMLHttpRequest对象是AJAX中非常重要的对象,所有的AJAX操作都是基于该对象的。

  2. XMLHttpRequest对象用来封装请求报文,我们向服务器发送的请求信息全部都需要封装到该对象中。

  3. 这里需要稍微注意一下,XMLHttpRequest对象并没有成为标准,但是现在的主流浏览器都支持该对象,而一些如IE6的老版本浏览器中的创建方式有一些区别,但是问题不大。

$.ajax()的使用

$.ajax({
	type:"请求方式",
	url:"请求路径",
	data:"请求携带参数数据",
	dataType:"服务器预期返回值类型,如:'text','json','xml','html'",
	contType:"告诉服务器,我要发什么类型的数据",
	success:function(){
		//请求成功时,被回调
	},
	error:function(){
		//请求失败时,被回调
	}
});

tip:

ajax请求dataType值为json,JQuery就会把后端返回的字符串尝试通过JSON.parse()尝试解析为JS对象。

dataType值为'text',返回的是json字符串。

dataType值改为'html',返回的是json字符串。

二、JSON的基本认识

什么是json

概念:关于JSON,最重要的是要理解它是一种数据格式,不是一种编程语言。虽然JSON与JavaScript具有相同的语法形式与JavaScript具有相同的语法形式,但JSON并不从属于JavaScript,很多编程语言都有针对JSON的解析器。

JSON的作用

JSON是用来跨平台传输数据的。

​> 思考:为什么要用JSON格式传递数据?

​    后端从数据库查询数据,得到一个List<User>集合,假设后端将List<User>集合传给前端,由于java语言与javaScript语言不同,js无法处理集合类型的数据。

    那么如果后端调用toString()方法,将集合转为字符串然后再传给前端呢?

​    假设前端接收到的是List<User>的字符串形式,这时又面临一个问题:js该如何从字符串中获取单独的属性呢?而且,每个类重写toString()的方法也不一样,这样就导致前端很难获取字符串中的属性。

​    因此,就有人提出了用JSON格式去传输数据:

前端以JSON格式传输数据,后端将JSON数据转换为相应的VO对象。

后端以JSON格式传输数据,前端将JSON数据转换为相应的JS对象。

三、 json可以表示的数据类型

  • 简单值:使用与JavaScript相同的语法,可以在json中表示字符串,数值,布尔值,和null。但json不支持JavaScript中的特殊值undefined。

  • 对象:对象作为一种复杂数据类型,表示的是一组无序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型值。

  • 数组:数组也是一种复杂数据类型,表示一组有序值的列表,可以通过数值索引,来防伪其中的值。数组的值也可以是任意类型——简单值,对象或数组。

    JSON不支持变量,函数或者对象实例

简单值

简单值:是JSON最简单的数据形式,如:数字 5 ,字符串:"hello word!"

javascript字符串与JSON字符串相比最大的区别在于:JSON字符串必须使用双引号(单引号会导致语法错误),布尔值和null也是有效的JSON形式。但在实际中json多用于表示复杂的数据形式,所以简单值在实际应用较少。

对象

JSON中的对象与JavaScript中的对象稍微有些不同。

区别1:JSON中的对象要求给属性加上 双引号,JavaScript中对象字面量表示可以不给属性加 双引号

JavaScript中对象字面量表示为:
          var person={
            name:"yuafn",   //可以不给属性name加 双引号
            age:20
          };
  但JSON中的对象要求给属性加上 双引号,实际上JavaScript中对象的字面量表示完全可以由JSON中的对象表示方法代替
          var person={
            "name":"yuafn",
            "age":20
          };

区别2:JSON中没有变量的概念,所以并没有声明变量。其次,没有末尾的分号

 JSON表示上述对象为:
          {
            "name":"nike",
            "age":20,
            "Mon":{
              "name":"nisa",
              "age":45
            }
          }

数组

JSON数组采用的就是JavaScript中的数组字面量形式。

JavaScript中数组字面量:var arr=[21,"nike",false];

JSON中数组表示:[20,"nike",true]

注:与JSON对象一样,没有变量的声明,末尾没有分号。

把数组和对象结合起来,可以表示更加复杂的数据集合

 [
          {
            "title":"JavaScript高级程序设计",
            "anothors":[
                "Nicholas"
            ],
            "edition":3,
            "year":2011
          },
          {
            "title":"JavaScript高级程序设计",
            "anothors":[
                "Nicholas"
            ],
            "edition":2,
            "year":2009
          },
          {
            "title":"JavaScript高级程序设计",
            "anothors":[
                "Nicholas"
            ],
            "edition":1,
            "year":2006
          }
        ]

四、json的基本语法

基本规则

* 数据在名称/值对中:json数据是由键值对构成的
			* 键用引号(单双都行)引起来,也可以不使用引号
			* 值得取值类型:
				1. 数字(整数或浮点数)
				2. 字符串(在双引号中)
				3. 逻辑值(true 或 false)
				4. 数组(在方括号中)	{"persons":[{},{}]}
				5. 对象(在花括号中) {"address":{"province":"陕西"....}}
				6. null
		* 数据由逗号分隔:多个键值对由逗号分隔
		* 花括号保存对象:使用{}定义json 格式
		* 方括号保存数组:[]

获取数据

		1. json对象.键名	---已经知道json对象的组成部分
		2. json对象["键名"] ---常用于遍历
		3. 数组对象[索引]   --- 常用于遍历
		
		4. 遍历
				 //1.定义基本格式
		        var person = {"name": "张三", age: 23, 'gender': true};
		
		        var ps = [{"name": "张三", "age": 23, "gender": true},
		            {"name": "李四", "age": 24, "gender": true},
		            {"name": "王五", "age": 25, "gender": false}];
		         //获取person对象中所有的键和值
		        //for in 循环
		       /* for(var key in person){
		            //这样的方式获取不行。因为相当于  person."name"
		            //alert(key + ":" + person.key);
		            alert(key+":"+person[key]);
		        }*/
		
		       //获取ps中的所有值
		        for (var i = 0; i < ps.length; i++) {
		            var p = ps[i];
		            for(var key in p){
		                alert(key+":"+p[key]);
		            }
		        }

五、JSON的解析与序列化

我们都知道可以使用JavaScript中的eval()函数解析json,返回JavaScript对象或者数组

因为JSON 文本格式在语法上与创建JavaScript对象的代码相同。
由于这种相似性,无需解析器,JavaScript程序能够使用内建的eval()函数,用JSON数据来生成原生的JavaScript对象。
实际上,eval() 函数可编译并执行任何 JavaScript 代码。这隐藏了一个潜在的安全问题。所以使用JSON解析器较为安全。
其实,JSON对象也有自己的方法可以把JSON数据结构解析为有用的JavaScript对象,

json对象的序列化与解析方法

ES5定义了全局对象JSON。支持这个对象的浏览器有:IE8+,FF,Chrome,Opera

JSON对象的两个方法:

  1. JSON.stringify():序列化作用,把JavaScript对象系列化为JSON字符串,

  2. JSON.parse():解析作用,把JSON字符串解析为原生JavaScript值(对象,或数组)

  • JSON.stringify():

     var book={
          title:"JavaScript高级程序设计",
          anothors:[
              "Nicholas"
          ],
          edition:3,
          year:2011
        };
       var toJsonText=JSON.stringify(book);
    

    说明:上面的例子使用 JSON.stringify() 把一个JavaScript对象解析成一个JSON字符串,然后将它保存在变量toJsonText中,默认情况下,JSON.stringify() 输出的JSON字符串不包含任何空格字符或缩进,因此保存在变量toJsonText中的字符串为:

      {"title":"JavaScript高级程序设计","anothors":["Nicholas"],"edition":3,"year":2011}
    
  • JSON.parse()

    将JSON字符串直接传递给 JSON.parse() 就可以得到相应的JavaScript值

     var bookCopy=JSON.parse(toJsonText);    //可以创建与book类似的对象
    

    补充:当创建的JavaScript对象为一个数组对象时,也可以使用

		var book=[{
            title:"JavaScript高级程序设计",
            anothors:[
                "Nicholas"
            ],
            edition:3,
            year:2011
          }];
          var toJsonText=JSON.stringify(book);  //是个JSON字符串
          alert(toJsonText);
          var arr=eval(toJsonText);  //eval()转换为对象或数组
          for (var i = 0; i < arr.length; i++) {
            alert(arr[i].title);
          }
          var bookCopy=JSON.parse(toJsonText);  //参数必须为一个JSON字符串,否则会出错
          alert(bookCopy[0].title);

序列化选项

​JSON.stringify()除了要序列化JavaScript对象以外,还接受两个参数,这两个参数用于指定以不同的方式序列化JavaScript对象。

所以JSON.stringify()一次可接受三个参数:

* 第一个是要序列化的JavaScript对象,

* 第二个参数:是个过滤器,可以是个数组,也可以是个函数
 1.当第二个参数为数组时,那么 JSON.stringify() 的结果中只包含数组中列出的属性
        var book={
          title:"JavaScript高级程序设计",
          anothors:[
              "Nicholas"
          ],
          edition:3,
          year:2011
        };
        var toJsonText=JSON.stringify(book,["title","edition"]);
      说明:toJsonText变量中保存的是:{"title":"JavaScript高级程序设计","edition":3}

      2.当第二个参数为函数时,传入的函数接收两个参数,属性名(键名)和属性值,根据属性名可以知道应该如何处理要序列化对象中的属性。

        属性名只能是字符串,而在属性值并非键值对儿结果时,属性名可以是空字符串。

        如果函数返回了undefined那么相应的属性就会被忽略。

          var book={
            title:"JavaScript高级程序设计",
            anothors:[
                "Nicholas"
            ],
            edition:3,
            year:2011
          };

          var toJsonText=JSON.stringify(book,function(key,value){
            switch(key){
              case "another":
                return value.join(",");   //如果键为"another",那么将数组连接成字符串
              case "year":
                return 5000;
              case "edition":
                return undefined;   //返回了undefined那么相应的属性就会被删除
              default:
                return value;
            }
          });

      说明:函数过滤器根据传入的键来决定结果。当函数运行时,传入对象book中的每一个键-值对儿将作为参数传进函数,而函数的返回值就是对应键的值。

      所以最后的JSON字符串为:

          {"title":"JavaScript高级程序设计","anothors":"Nicholas","year":5000}
  • 第三个参数:是一个可选的选项,表示是否在返回的JSON字符串中保留缩进。

    1.如果第三个参数是一个数字,表示的是每个级别缩进的空格数
            var book={
              title:"JavaScript高级程序设计",
              anothors:[
                  "Nicholas"
              ],
              edition:3,
              year:2011
            };
    
            var toJsonText=JSON.stringify(book,null,4);
    
            结果为:
                {
                    "title":"JavaScript高级程序设计",
                    "anothors":[
                        "Nicholas"
                    ],
                    "edition":3,
                    "year":2011
                }
    
          说明:我们可以看到,结果不仅缩进了四个空格,而且也结果字符串中换了行,其实只要传入了有效的控制缩进的参数,结果JSON字符串字符串就会包含换行符(只缩进不换行意义不大),最大缩进空格数为10,所有大于10的值会自动转换为10。
    
        2.如果参数是一个字符串,而非数值,则这个字符串将在转换后的JSON字符串中用作缩进字符,和数字类似
    
    

解析选项

JSON.parse() 也会接收另外一个参数,该参数为函数(又称还原函数),和JSON.stringify() 接受函数参数时类似,都是在每个键值对上面调用。

同样,如果函数返回undefined,表示要从结果中删除相应的键和属性,如果返回其他值,则表示该值插入到结果中。

将日期字符串转换为Date()对象时,经常用到还原函数

var book={
        title:"JavaScript高级程序设计",
        anothors:[
            "Nicholas"
        ],
        edition:3,
        year:2011,
        releaseDate:new Date(2016,3,12)
      };
      var toJsonText=JSON.stringify(book);
      var copyBook=JSON.parse(toJsonText,function(key,value){
          if(key=="releaseDate"){
            return new Date(value);
          }else{
            return value;
          }
      });
      alert(copyBook.releaseDate.getFullYear());  //2016

说明:上面代码先为book对象新增一个releaseDate属性,属性值为Date()对象,这个对象经过序列化之后变成一个JSON字符串,然后经过解析又在copyBook还原一个Date()对象,所以能够调用该属性中的getFullYear()方法。

posted @ 2020-12-02 20:35  沙滩拾贝  阅读(131)  评论(0编辑  收藏  举报