12.第21章:Ajax与Comet

1.XMLHttpRequest对象


1.1 创建XMLHttpRequest对象

IE7及之前的版本:不支持new,要兼容IE7及之前版本,需要按照如下方法。



若不需要兼容IE7及之前版本

let xmr=new XMLHttpRequest();

1.2 调用open方法
接收三个参数:请求方式(get,post)、请求地址url、同步异步(默认异步,值为true,可以不提供最后一个参数,使用默认参数)

let xhr=new XMLHttpRequest();
xhr.open("GET",url,true);

1.3 调用send方法
接收一个参数:要发送的数据data,没有就是null

  • 发送get请求
let xhr=new XMLHttpRequest();
xhr.open("GET",url+"?name1=value&name2=value2",true);
 xhr.sent();
  • 发送post请求时,需要设置请求头部
let xhr=new XMLHttpRequest();
 xhr.open("POST","http://",true);
//设置发送数据格式
 xhr.contentType="application/x-ww-form-urlencoded";
 xhr.sent("name1=value&name2=value2");

HTTP头部信息:

1.4 添加onreadystatechange事件,为了跨浏览器的兼容性,将其放在open()方法之前。
readyState表示请求的状态,当请求的状态值发生变化时,会触发onreadystatechange()事件。

  • get请求全部代码
let xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
//表示请求完成
if(xhr.readyState==4){
     //表示http状态码的取值
    if(xhr.status>=200&&xhr.status<300||xhr.status==304){
     let responceJson=JSON.parse(xhr.responseText);      
    }
    else{
      alert("request not sucess:"+xhr.status);
    }
}

xhr.open("GET",url+"?name1=value&name2=value2",true);
 xhr.sent();
  • post请求全部代码
let xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
  if(xhr.readyState==4){
    if(xhr.status>=200&&xmr.status<300||xmr.status==304){
      let responceJson=JSON.parse(xhr.responseText);    
   }
     else{
      alert("request not sucess:"+xhr.status);
    }
  }
 xhr.open("POST","http://",true);
//设置发送数据格式
 xhr.contentType="application/x-ww-form-urlencoded";
 xhr.sent("name1=value&name2=value2");
}

HTTP状态码:
500:内部错误
404:找不到页面(page not found)
403:禁止访问(forbidden)
304:没有被修改
200:一切正常

  • 自己实现一个ajax
<script>
  function createAjax(url,method,data) {
      let xmlHttp=window.XMLHttpRequest?new XMLHttpRequest():
          new ActiveXObject('Microsoft.XMLHTTP');
      
      xmlHttp.onreadystatechange=function () {
          //readyState等于4表示发送完成
          if(xmlHttp.readyState===4){
              if((xmlHttp.status>=200&&xmlHttp.status<300)||xmlHttp.status===304){
                  //成功之后的处理
                  let responseJson=JSON.parse(xmlHttp.responseText);
              }
              else{
                  alert('请求失败'+xmlHttp.status);
              }
                  
          }
      };
      if(method==='POST')
      {
          xmlHttp.open(method,url,true);
          xmlHttp.setRequestHeader('content-type','application/x-www-form-urlencoded');
          xmlHttp.send(JSON.stringify(data));
          
      }
      else {
          url=url+'?data='+JSON.stringify(data);
          xmlHttp.open(method,url,true);
          xmlHttp.send();
      }
      
  }    
</script>

2 XMLHttpRequest 2级

2.1 FormData

之前使用post发送表单请求



使用FormData实现,不需要设置头部


3.跨域资源共享

默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。
CORS定义了在访问跨域资源时,浏览器与服务器应该如何沟通,基本思想是:使用自定义的Http头部让浏览器和服务器进行沟通,从而决定请求或响应应该成功或者失败。


3.1 IE对CORS的实现

微软在IE8中引入XDomainRequest类型,如下是XDR与XHR类型的不同之处:



涉及到的方法:
1)open()方法只接收两个参数:请求类型、url,所有XDR请求都是异步操作。
2)请求成功后会触发load事件,响应的数据会保存在responseText属性中。
3)请求错误会触发error事件。
4)请求返回前调用abort()方法可以终止请求。
5)XDR也支持timeout属性和ontimeout事件处理程序。
6)contentType属性,用来表示发送数据的格式。

let xdr=new XDomainRequest();
//请求成功
xdr.onload=function(){
    alert(xdr.responseText);
}
//请求失败
xdr.onerror=function(){
     alert(“请求失败”);
}
xdr.timout=1000;
xdr.ontimeout=function(){
    alert("请求超时");
}
xdr.open("post","http://");
//设置发送数据格式
xdr.contentType="application/x-ww-form-urlencoded";
xdr.sent("name1=value&name2=value2");

3.2 其他浏览器对CORS的实现

通过XMLHttpRequest对象实现了对CORS的原生支持。无需额外编写代码。

let xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
   if(xhr.status>=200&&xhr.status<300||xhr.status==304){
       alert(xhr.responseText);
     }
    else{
        alert("请求失败,状态码"+xhr.status);
    }
}
xhr.open("get","http://",true);
xhr.send(null);
}

对于本地资源,最好使用相对URL
访问远程资源,使用绝对URL。

3.3 跨浏览器的CORS
function createCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    //如果xhr里面有withCredentials属性,说明是非IE浏览器
    if("withCredentials" in xhr){
    xhr.open(method,url,true);
  }else if(typeOf XDomainRequest !="undefined"){
      xhr=new XDomainRequest();
      xhr.open(method,url);
   }else{
      xhr=null;
    }
return xhr;
}

let request=createCORSRequest("get","http:");
if(request){
request.onload=function(){
    alert(request.responseText);
}
request.onerror=function(){
   alert("请求失败");
}
request.send();
}

3.其他跨域技术

3.1 图像Ping

图像Ping是与服务器进行简单,单向的跨域通信的一种方式,请求的数据是通过查询字符串形式发送的,但响应可以是任意内容,通常是像素图或204响应。
图像Ping,浏览器得不到任何具体数据,但通过侦听load和error事件,它能知道响应是什么时候接收到的。


3.2 JSONP

JSONP由两部分组成:回调函数、数据
回调函数是当响应到来时应该在页面中调用的函数,数据就是传入回调函数的JSON数据。
JSONP通过动态<script>元素来使用的。

<script>
    /*jsonp*/
    function handleCallback(data){
        //这里就是想要 得到的信息
        console.log(data);

    }
    let script=document.createElement('script');
    script.src='http://coding.imooc.com/api/js?callback=handleCallback';
    document.body.insertBefore(script,document.body.firstChild);
</script>
  • 与图像ping相比优点:
    能够直接访问响应文本,支持浏览器与服务器的双向通信。
  • 缺点:
    JSONP是从其他域中加载代码执行,如果其他域不安全,只能放弃调用。
    无法确定JSONP请求是否失败。
3.3 Comet

Ajax是从页面向服务器请求数据的技术,而Comet是一种服务器向页面推送数据的技术。Comet能够让信息近乎实时的被推送到页面上。
Comet有两种实现方式:长轮询(是短轮询的翻版)和流

  • 短轮询
    浏览器定时向服务器发送请求,看有没有更新的数据。


    短轮询
  • 长轮询
    页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求,页面打开期间一直持续不断。


    长轮询
  • HTTP流
    流不同于轮询,它在页面的整个生命周期内只使用一个HTTP连接,就是浏览器向服务器发送一个请求,而服务器保持连接打开,周期性向浏览器发送数据。


3.4 SSE 服务器发送事件

是支持短轮询,长轮询,HTTP流的API,实现Comet就容易很多。


  • EventSource对象
    readyState属性:0,表示正在连接到服务器,1表示打开了连接,2表示关闭连接。
    三个事件:



    服务器返回的数据以字符串的形式保存在event.data中。

let source=new EventSource("myevents.php");
source.onmessage=function(event){
    var data=event.data;
}
3.5 Web Sockets

在一个单独的持久连接上提供全双工、双向通信。

  • WebSocket对象


readyState属性:表示当前状态



send()方法:只能发送纯文本数据,复杂的数据必须序列化。



事件:
message事件,当服务器向客户端发来消息时触发。


  • SSE与Web Sockets选择
    1.是否有自由度建立和维护Web Socket服务器
    2.是否需要双向通信。如果只需读取服务器数据,SSE容易实现,如果必须双向通信(聊天室),
    选择Web Sockets
3.6 安全

可以通过XHR访问的任何URL也可以通过浏览器或服务器来访问。


图片.png

XSS:跨站脚本攻击
别人的js代码在你的页面里面执行。

get :数据放在url传输 数据量小 缓存 作为表单提交看得见参数
post:数据在body中传输 数据量大 不缓存 作为表单提交看不见

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容