《JavaScript高级程序设计 第三版》学习笔记 (十二)Ajax详解

一、JSON

1.使用XML在服务器和浏览器之间进行数据交换太浪费带宽,因而出现了新的数据结构JSON。JSON是包含了简单值、对象、数组的严格的JS子集,不支持变量、函数或对象实例。很多语言也有各自的JSON解析器和序列化器。
2.不能将JSON写成简单的js字面量,否则只能在js中使用,而其他语言会解析不了。JSON要求严格的地方主要有:字符串值必须用双引号;对象属性必须用双引号;同一个对象中绝不应该出现两个同名属性。

3.解析和序列化

(1)JSON.stringify可以把JSON对象转换成字符串(序列化),可以再带两个参数。如果第二个参数是字符串数组,则不在数组中的属性全部丢弃。如果第二个参数是函数,则把键和值回传给参数,经过函数处理,返回值作为键值;返回undefined,相应属性会被忽略。第三个参数是为转换完的字符串自动加入换行符和缩进符,参数表示缩进的空格数,最大10。
[javascript]  view plain  copy
  1. //小实验  
  2. var json={  
  3.     "name":"brain",  
  4.     "sex":"male",  
  5.     "age":15      
  6. }  
  7. var jsonText=JSON.stringify(json);  
  8. var jsonText2=JSON.stringify(json,["name"]);  
  9. var jsonText3=JSON.stringify(json,function(key,value){  
  10.     if(key=="sex"){  
  11.         if(value=="male"){  
  12.             return 0;     
  13.         }else{  
  14.             return 1;     
  15.         }  
  16.     }else if(key=="age"){  
  17.         return;  
  18.     }else{  
  19.         return value;     
  20.     }  
  21. });  
  22. var jsonText4=JSON.stringify(json,null,4);  
  23.   
  24. console.log(jsonText);//{"name":"brain","sex":"male","age":15}   
  25. console.log(jsonText2);//{"name":"brain"}   
  26. console.log(jsonText3);//{"name":"brain","sex":0}   
  27. console.log(jsonText4);  
  28. /* 
  29. { 
  30.     "name": "brain", 
  31.     "sex": "male", 
  32.     "age": 15 
  33.  
  34. */  

(2)使用eval会存在安全隐患,因为json中可能存在恶意代码。JSON.parse可以把字符串转换成json对象。parse可以再带一个参数。第二个参数是一个还原函数,传入key和value,返回值作为键的值放入结果对象。
[javascript]  view plain  copy
  1. //小实验  
  2. var jsonText='{"name":"brain","sex":"0","age":15}';  
  3. var json1=JSON.parse(jsonText);  
  4. var json2=JSON.parse(jsonText,function(key,value){  
  5.     if(key=="sex"){  
  6.         if(value=="0"){  
  7.             return "male";    
  8.         }else{  
  9.             return "female";      
  10.         }  
  11.     }else{  
  12.         return value;  
  13.     }  
  14. });  
  15. console.log(json1.sex);//0  
  16. console.log(json2.sex);//male  

二、Ajax

1.Ajax是Asynchronous JavaScript And XML的缩写。可以理解为异步基于js的服务器通讯机制。但现在基本上没人把XML用作Ajax的数据结构,转而多使用JSON。
2.IE8+和标准浏览器,目前都支持XMLHttpRequest对象,简称XHR,用于完成Ajax整个过程。
(1)XHR.open()方法,做请求准备。可待三个参数:第一个表示请求类型,GET或POST;第二个请求地址,可以是具体的初级脚本文件,也可以是MVC中的路由地址;第三个表示是否异步发送请求(默认为true)。
(2)XHR.send()方法,发送数据。可带一个参数,即实际发送的数据体,一般为字符串。
(3)XHR.responseText属性,作为接收主体,从服务器得到的字符串。
(4)XHR.responseXML属性,从服务器得到的XML文档,前提是内容类型为“text/xml”或“application/xml”。
(5)XHR.status属性,响应的http状态,为数值。
(6)XHR.statusText属性,http状态的说明。
(7)XHR.onreadystatechange事件,只要status状态发生改变,就会触发这个事件,根据XHR.status的值确定通信是否完成。此事件必须在open前绑定,因为未调用open会改变status。
(8)XHR.abort方法,取消异步的通信。默认的XHR都是异步通讯,在通讯过程不会发生js阻塞,所以,同步通信很少使用。
(9)XHR.setRequestHeader(header,value)方法,设置http头部信息,不太常用,但必要时候很好用。
3.完整实例
[javascript]  view plain  copy
  1. var xhr=new XMLHttpRequest();  
  2. xhr.onreadystatechange=function(){  
  3.     console.log(xhr.status+":"+xhr.statusText);   
  4. }  
  5. xhr.open("post","http://www.hostname.com");  
  6. xhr.send("?123");  

4.load事件
(1)多数浏览器支持load事件:loadstart、progress、error、abort、load。这些事件加在一起,可以完全替代onreadystatechange。
(2)有些人使用这些load事件来异步加载js,而且用户体验更好。

三、跨域

1.跨域永远是资源共享不可回避的问题,但由于安全限制,Ajax默认是不支持跨域的。
2.IE的解决方法,提供了XDomainRequest类型实现跨域通信。用法和XHR差不多,但限制更严格,比如不能发送cookies、只能设置header的Content-Type、不能访问响应头信息、只支持get和post、只支持异步。
3.标准浏览器做法,在open的url中写入绝对地址。实验证明,现在已经不行了。
4.其他跨域技术
(1)图像ping,利用一些可以跨域的html标签的src属性,可以完成跨域。图像是动态创建img,使用这种方法,浏览器得不到任何数据,但能在URL中写入信息通过GET形式发送给服务器。通过监听load事件和error事件能知道响应是什么时候接收到的。
[javascript]  view plain  copy
  1. //小实验  
  2. var img=new Image();  
  3. img.οnlοad=function(){  
  4.     console.log("loaded");    
  5. }  
  6. img.οnerrοr=function(){  
  7.     console.log("error");     
  8. }  
  9. img.src="http://www.hostname.com";  

(2)JSONP,JSONP是JSON的一种新方法,JSON with padding。
  JSONP由两部分数据组成:回调函数和数据。典型的JSONP请求如http://hostname/json/?callback=handleResponse。而服务器回传的数据是这样的handleResponse({"name":"tom",age:25})。由于JSONP是有效的js代码,因此要利用script标签传动。
[javascript]  view plain  copy
  1. //小实验  
  2. function handleResponse(obj){  
  3.     console.log(obj.name);    
  4. }  
  5. var script=document.createElement("script");  
  6. script.src="http://hostname/json/?callback=handleResponse";  
  7. document.body.insertBefore(script,document.body.firstChild);  
JSONP非常流行,能够直接访问响应文本,支持浏览器与服务器之间跨域双向通信。但不足是明显的:从其他域加载代码不安全;确定JSONP请求是否失败不太容易,不是所有浏览器都支持<script>标签的onerror事件。
(3)Comet,ajax是向服务器发请求,处理返回数据,通信是单向的。而Comet更加先进,能够让服务器推动信息给浏览器,实现了双向通信。
  实现双向通信,一种方法是长短轮询,来伪造一个连接。第二种方式是http流,在页面整个声明周期内,使用一个http连接,服务器始终保持连接打开,周期性地向浏览器发送数据。目前的实现方法,是在服务器中写一个轮询(感觉换汤不换药,不可能像socket一样保持连接,那没有意义,也相当耗费资源)。Comet技术是通过XHR实现的,只要status变为3,就会接收状态就会改变,然后比较responseText的前后变化以获得新数据。
//服务器写法
[php]  view plain  copy
  1. <?php  
  2.     $i=0;  
  3.     while(true){  
  4.         echo "$i;";  
  5.         flush();//将cache中的数据发给浏览器  
  6.         sleep(10);  
  7.         $i++  
  8.     }  
  9. ?>  

(4)WebSockets,目标是在一个单独的持久连接上提供全双工、双向通信。WebSocket使用ws和wss(安全环境)做协议头。API和其他语言的socket没什么大区别。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值