js-ajax详解

496 阅读5分钟

ajax

  1. 创建ajax

function createXHR(){
    if(typeOf XMLHttpRequest != 'undefined'){
        return new XMLHttpRequest();
    }else if(typeOf ActiveXObject != 'undefined'){
        if(typeOf arguments.callee.activeXString != 'string'){
                let version = ['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp'];                for(i=0;i<version.length;i++){
                    try {
                        new ActiveXObject(version[i]);
                        arguments.callee.activeXString = version[i];
                        break;
                    } catch(ex) {
                        //跳过
                    };
                };
        };
    }else{
        throw new Error('No XHR object available.');
    };
};

let xhr = new createXHR();

2.调用open();

  • 三个参数:要发送的请求的类型('get','post'等);请求的URL;是否异步发送请求的布尔值;
  • 调用:xhr.open('get','example.php',true);
  • 说明两点:一是URL相对于执行代码的当前页面(也可以是绝对路径);二是调用open()方法并不会真正发送请求,而是启动一个请求以备发送。
  • 注意:同源策略(同域名,同协议,同端口);

3.调用send();

  • 一个参数:作为请求主体发送的数据,如果不需要必须传null.
  • 调用send()后,请求就会被分派到服务器。

4.监听readystatechange事件,获取xhr的readyState和status属性值

  • 同步请求判断xhr的status属性就可以,异步请求既需要获取xhr的readyState属性又要获取xhr的status属性
  • readyState

   1)该属性表示请求/响应的当前活动阶段

   2)属性值

  • 0:未初始化。尚未调用open()方法;
  • 1:启动。已经调用open()方法,但尚未调用send()方法;
  • 2:发送。已经调用send()方法,但尚未收到响应;
  • 3:接收。已经收到部分响应数据;
  • 4:完成。已经收到全部响应数据,而且已经可以在客户端使用了。   
  • status

   1)该属性表示:响应的HTTP状态

    2)成功返回(200<=status<300和304)

  • xhr响应返回填充的属性

   1)responseText:作为响应主体被返回的文本

    2)responseXML:如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着包含着响应数据的XML DOM文档。

    3)statusText:HTTP状态的说明

let xhr = new createXHR();

xhr.onreadystatechange = function(){
    if(xhr.readyState==4){
        if((xhr.status>=200 && xhr.status<300) || xhr.status == 304){
            alert(xhr.responseText);
        };
    };
};

xhr.open('get','example.text',true);

xhr.send(null)

5.abort()方法

  • 调用这个方法后,XHR对象会停止触发事件,而且也不允许访问任何与响应有关的对象属性

6.setRequestHeader()

  • 接收两个参数:头部字段的名称和头部字段的值。必须在open()方法之后和send()方法之前调用setRequestHeader方法

备注:

1.get请求

  • 适用:用于向服务器查询某些信息。
  • 可以将查询字符串参数追加到URL的末尾,但是要正确编码。添加参数函数:

function addURLParam(url,name,value){
    url += (url.indexOf('?')==-1?'?':'&');
    url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
    return url; 
};

2.post请求

  • 适用:通常用于向服务器发送应该被保存的数据。

3.get和post的优缺点:

  • 资源:psot消耗的资源更多
  • 速度:传送的数据相同,get的速度最多是post的两倍


解决跨域的方法:(参考https://www.cnblogs.com/sdcs/p/8484905.html)

  1. 通过jsonP跨域
  • 原理:通过script标签来引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且把我们需要的json数据作为参数传入。但是jsonp这种方式是需要服务端对应页面进行相应配合的。

2.通过修改document.domain来跨子域

  • 适用:浏览器中不同域的框架之间是不能进行js交互的
  • 例如:www.example.com/a.htmlexample.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
  • 注意:修改document.domain的方法只适用于不同子域的框架间的交互。如果你想通过ajax的方法去与不同子域的页面交互,除了使用jsonp的方法外,还可以用一个隐藏的iframe来做一个代理。原理就是让这个iframe载入一个与你想要通过ajax获取数据的目标页面处在相同的域的页面,所以这个iframe中的页面是可以正常使用ajax去获取你要的数据的,然后就是通过我们刚刚讲得修改document.domain的方法,让我们能通过js完全控制这个iframe,这样我们就可以让iframe去发送ajax请求,然后收到的数据我们也可以获得了。

3.使用window.name来进行跨域

  • window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
  • 注意:window.name的值只能是字符串的形式,这个字符串的大小最大能允许2M左右甚至更大的一个容量,具体取决于不同的浏览器,但一般是够用了。
  • 原理:在a.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后a.html再去得到iframe获取到的数据。

    

4.通过HTML5中新引入的window.postMessage()方法来跨域传送数据。

  • 原理:window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
  • 参数:第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。
  • 接收:要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。
  • 适用:一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候,我们说过,不同域的框架间是可以获取到对方的window对象的,而且也可以使用window.postMessage这个方法