黑马程序员技术交流社区

标题: Ajax的使用以及跨域(上) [打印本页]

作者: 西安中心教研部    时间: 2017-7-31 00:01
标题: Ajax的使用以及跨域(上)
Ajax相信大家都听说过,接下来这几篇文章就来说说关于Ajax的一些知识,从而也顺道引出来在实际工作过程中经常使用的一下技术:跨域。
首先我们先来看Ajax,Ajax简单的来说,就是一个异步的javascript请求,用来获取后台服务端的数据,为什么要异步的呢?很简单,因为获取后台网络数据是需要时间的,如果同步的话,将会讲当前界面卡住,造成非常不友好的用户体验。
在元素JS中来实现Ajax主要的类就是XMLHttpRequest,它的使用一般有四个步骤:
1、 创建XMLHttpRequest对象
2、 准备发送网络请求
3、 开始发送网络请求
4、 指定回调函数
没错,就是这么简单的四个步骤,下面我们就通过代码来将这四个步骤实现出来。
第一步,创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();

第二步:准备发送网络请求
xhr.open('get','./01check.php?username='+uname+'&password='+pw,true)
调用open方法,这里面有三个参数,第一个参数代表的这个Http请求是以get方式还是post方式,如果是get请求,则如果有参数的话,则需要将参数跟在url的后面,而如果是post请求,参数应该跟在请求体中。
第二个参数就是这个Http请求的url地址。这个url地址后面是否有?加参数,得取决于第一个参数是get还是post
第三个参数代表这个Http请求是同步的还是异步的。false代表同步,true代表异步。这个参数一般都是写true,因为谁都不想在网络请求的时候,将这个网页卡住吧?不过对于学习来说的话,我们等等可以测试一下false的效果。

第三步:开始发送网络请求
xhr.send(null);
调用send方法,传递一个null。需要注意的是,如果你在第二步的请求方式为get的话,那么这里传null,如果在第二步的请求方式为post的话,这里就需要传入你所需要传递给服务器的参数了。因为之前我们说过,post请求的参数并不是跟在url后面的,而是跟在请求体中,而send方法中的参数就是会被设置到请求体中。因此,对于post请求,需要在这里传递参数。如:
var param = 'username='+uname+'&password='+pw;
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send(param);
需要注意的是,如果使用post请求,并且又有参数的话,那么对于xhr就必须设置请求头信息,否则服务端接受不到参数。这个写法都是固定的,如有需要直接复制即可,不需要背。

第四步,指定回调函数,xhr.send方法调用完之后,http请求就发送出去了。由于在第二步中,我们设置了请求为异步请求,异步请求不能直接获得结果,只能通过监听回调的方式来得到响应数据。
xhr.onreadystatechange = function(){
    if(xhr.readyState== 4){
        if(xhr.status == 200){
            alert(xhr.responseText);
        }
    }
}
上诉代码的4和200代表的正常得到数据,服务器响应正常,那么这时候我们就可以通过xhr.responseText来获取到服务器给我们返回的数据了。
这里给出readyState和status的常用值代表含义的对应关系

好,通过上诉步骤,我们就能实现Ajax来完成异步请求了。完整的代码如下:
get请求:
<script type="text/javascript">
window.onload = function(){
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        var uname = document.getElementById('username').value;
        var pw = document.getElementById('password').value;
        
var xhr = new XMLHttpRequest();
xhr.open('get','./01check.php?username='+uname+'&password='+pw,true);
        
xhr.send(null);
        
xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    var data = xhr.responseText;                                            
                }
            }
        }
    }
}
</script>

post请求:
<script type="text/javascript">
window.onload = function(){
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        var uname = document.getElementById('username').value;
        var pw = document.getElementById('password').value;
        
var xhr = new XMLHttpRequest();
        xhr.open('post','./01check.php',true);
        varparam = 'username='+uname+'&password='+pw;
       xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
               xhr.send(param)
        
xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    var data = xhr.responseText;                                            
                }
            }
        }
    }
}
</script>

关于原生的Ajax请求,还有一点需要说明的就是在第二个步骤设置的同步还是异步的标识位。也就是xhr.open方法的最后一个参数,这个值一般都是true,但是总有人爱装牛角尖,就会问如果是false会怎样?
前面已经说过了,这个值true代表是异步请求服务器的数据,false代表同步请求服务器的数据。如果是同步请求,那么在xhr获取到数据之前,整个浏览器都是卡在send方法等待数据返回,所以此时用户操作界面是没有任何效果的,按钮点击不了,页面也滚动不了,体验非常的差。这里需要说明的是,如果真有人把这个参数写成false的话,那么在第四步中获取数据的方式将会有所改变。如下:
<script type="text/javascript">
window.onload = function(){
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        var uname = document.getElementById('username').value;
        var pw = document.getElementById('password').value;
        
var xhr = new XMLHttpRequest();
xhr.open('get','./01check.php?username='+uname+'&password='+pw,false);
        
xhr.send(null);
        
if(xhr.readyState == 4){
           if(xhr.status == 200){
             var data = xhr.responseText;                                            
          }
        }
     }
}
</script>

注意到没有,如果是同步请求的话,那么我们就不需要监听onreadystatechange方法。因为xhr在send方法调用的时候,是一直卡在这个方法中的。一旦这个方法结束,那么xhr就已经成功的访问到服务器的数据了,不需要做readystatechange的监听。换句话说,这时候readystatechange也监听不到了。因为xhr.onreadystatechange= function(){}这行代码是在xhr.send之后调用的,对于同步方法来说,send方法中xhr.readystate已经发生了变化,最后变为4之后才跳出send方法继续向下执行。
最后,还需要讲一个稍微不太重要的东西,就是XMLHttpRequest的创建对于低版本的IE需要做兼容。因为低版本的IE可能没有XMLHttpRequest这个对象。做法如下:
var xhr = null;
if(window.XMLHttpRequest){ //能力测试
    xhr = new XMLHttpRequest();//标准
}else{
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

好,到目前为止呢,我们就讲了关于Ajax在原生js下的使用方式和注意事项,总结来说有以下几点:
1、XMLHttpRequest对象创建的兼容处理
2、get请求post请求在代码上有什么差异
3、同步和异步的影响,以及同步和异步获取数据的差异。
其实在实际开发中,我们比较少自己使用原生的js代码来实现Ajax,而是使用第三方库,比如jQuery,那么jQuery如何来使用Ajax,我们自己能不能封装一个类似jQuery一样的Ajax调用方式呢?我们下一篇文章再来说明一下。

作者: 多多酱    时间: 2017-7-31 00:56
ding顶一个

作者: 沈唁    时间: 2017-7-31 07:55
厉害了我的哥

作者: laber    时间: 2018-1-19 15:25
厉害了老铁




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2