zoukankan      html  css  js  c++  java
  • AJAX的具体使用

    一、GET请求

    ①GET请求传递参数通常使用的是问号传参,即在请求地址上加上?参数,从而传递数据到服务端

    ②一般在GET请求数据时,无需设置响应体,可以传null或者干脆不传

    ③一般情况下URL传递的都是参数性质的数据,而POST一般都是业务数据

    <?php
        //test.php服务端文件
        //返回的响应就是数据,对于返回数据的地址一般称之为接口(有输入有输出),形式上上是web形式
        $data=array(
            array('id' => 1,'name' =>'刘备','age' => 30),
            array('id' => 2,'name' =>'关羽','age' => 29),
            array('id' => 3,'name' =>'张飞','age' => 28)
        );
        //处理数据
        if(empty($_GET['id'])){
            //没有ID则获取全部数据
            //因为HTTP中约定报文的内容就是字符串,需要传递给客户端的是信息是一个有结构的数据
            //这种情况下一般采用json作为数据格式
            $json=json_encode($data);
            echo $json;
        }else{
            //传递了ID只获取一条
            foreach($data as $item){
                if($item['id']==$_GET['id']){
                    $json=json_encode($item);
                    echo $json;
                }
            }
        }
    ?>
    <body>
        <ul id="list"></ul>
        <script>
            var listElement=document.getElementById("list");
            var xhr=new XMLHttpRequest();
            xhr.open('GET','http://localhost/test.php');
            xhr.send();
            xhr.onreadystatechange=function(){
                if(this.readyState!==4) return;
                //JSON.parse()方法用于将一个JSON字符串转换为对象
                var data=JSON.parse(this.responseText);
                //遍历对象
                for(var i=0;i<data.length;i++){
                    //增加一个li元素
                    var liElement=document.createElement('li');
                    //li元素里面写入的是服务端数据的name值
                    liElement.innerHTML=data[i].name;
                    //便于后面获取当前被点击元素对应数据的ID
                    liElement.id=data[i].id;
                    //把li元素添加到ul里面
                    listElement.appendChild(liElement);
                    //为li元素注册点击事件,使用addEventListener的好处是可以为一个元素注册多个事件,不会冲突
                    liElement.addEventListener('click',function(){
                        //通过AJAX操作获取服务器端对应数据的信息
                        var xhr1=new XMLHttpRequest();
                        xhr1.open('GET','http://localhost/test.php?id=' + this.id);
                        xhr1.send();
                        xhr1.onreadystatechange=function(){
                            if(this.readyState!==4) return;
                            var obj = JSON.parse(this.responseText);
                            console.log(obj);
                            alert(obj.age);
                        };
                    });
                }
            }
        </script>
    </body>

    二、POST请求

    ①post请求过程中,都是采用请求承载需要提交的数据

    ②open()方法的第一个参数就是设置请求的method

    ③setRequestHeader中需要设置Content-Type的格式与send( )里参数的格式相对应

    ④用户可以自定义加载页面,只要利用display的none和block结合请求的状态变化就可以实现

    ⑤案例:

    <?php
        //test.php服务端文件
        //接收用户端提交的用户名和密码
        if(empty($_POST['username']) || empty($_POST['password'])){
            exit('请提交用户名和密码');
        }
        //校验
        $username=$_POST['username'];
        $password=$_POST['password'];
        if($username==='admin' && $password='123'){
            exit('登录成功');
        }
        exit('用户名或者密码错误');
    ?>
    <body>
        <table border="1">
            <tr>
                <td>用户名</td>
                <td><input type="text" name="username" id="username"></td>
            </tr>
            <tr>
                <td>密码</td>
                <td><input type="password" name="password" id="password"></td>
            </tr>
            <tr>
                <td></td>
                <td><button type="submit" id="btn">登录</button></td>
            </tr>
        </table>
        <script>
            //声明变量
            var btn=document.getElementById("btn");
            var txtUsername=document.getElementById("username");
            var txtPassword=document.getElementById("password");
            //为btn注册点击事件
            btn.onclick=function(){
                //获取用户填入的值
                var username=txtUsername.value;
                var password=txtPassword.value;
                //通过xhr发送一个POST请求
                var xhr=new XMLHttpRequest();
                xhr.open('POST','http://localhost/test.php');
                //设置请求头的格式,与请求体urlencoded的格式对应
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                //设置请求体,格式为urlencoded,注意`{}`这样的写法
                xhr.send(`username=${username}&password=${password}`);
                //根据服务端的反馈,作出页面提示
                xhr.onreadystatechange=function(){
                    if(this.readyState!==4) return;
                    console.log(this.responseText);
                }
            }</script>
    </body>

    三、同步和异步

    ①概念

    • 同步可以理解为一个人在同一时刻只能做一件事情,在执行一些耗时的操作(不需要看管)不去做其他的事,只是等待。同步的思想是:所有的操作都做完,才返回给用户。这样用户在线等待的时间太长,给用户一种卡死了的感觉(就是系统迁移中,点击了迁移,界面就不动了,但是程序还在执行,卡死了的感觉)。这种情况下,用户不能关闭界面,如果关闭了,即迁移程序就中断了。
    • 异步可以理解为在执行一些耗时的操作时(不需要看管)去做别的事,而不是等待。将用户请求放入消息队列,并反馈给用户,系统迁移程序已经启动,你可以关闭浏览器了。然后程序再慢慢地去写入数据库去。这就是异步。但是用户没有卡死的感觉,会告诉你,你的请求系统已经响应了。你可以关闭界面了。

    ②设置:open()方法第三个参数是传入一个bool值,其作用就是设置此次请求是否采用异步方式执行 ,默认为true,如果需要同步执行可以通过传递false实现

    <script>
            console.log('before ajax');
            var xhr=new XMLHttpRequest();
            xhr.open('GET','http://localhost/test.php',true);
            xhr.send(null);
            xhr.onreadystatechange=function(){
                if(this.readyState===4){
                    console.log('加载完成');
                }
            }
            console.log('after ajax');
            //控制台输出:
            //before ajax
            //after ajax
            //加载完成
        </script>
    <script>
            var xhr=new XMLHttpRequest();
            xhr.open('GET','http://localhost/test.php',false);
            //同步方式执行会在send()发送请求以后等待一段时间,直到readyState为4才会继续往下执行代码
            xhr.send(null);
            //所以不需要注册事件,就可以拿到数据了,或者如果需要注册事件,一定需要在send方法调用之前注册事件,否则无法触发
             console.log(xhr.readyState);//4
            // xhr.onreadystatechange=function(){
            //     if(this.readyState===4){
            //         console.log('加载完成');
            //     }
            // }
            console.log(xhr.responseText);//1529918265
            //并且控制台会提醒这种方式会导致用户体验不佳:
            //[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.
        </script>

    ③结论:

    • 同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。
    • 异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好。

    四、响应数据类型

    • 如果服务端返回的各种格式的数据,这种格式的数据都需要在客户端使用JavaScript解析
    • XML是一种数据描述手段,由于数据冗杂太多,现在基本被淘汰
    <?xml version="1.0" encoding="utf-8" ?>
    <users>
      <user>
        <username>张三</username>
        <age>23</age>
      </user>
      <user>
        <username>李四</username>
        <age>24</age>
      </user>
    </users>
    <script>
            var xhr=new XMLHttpRequest();
            xhr.open('GET','user.xml');
            xhr.send();
            xhr.onreadystatechange=function(){
                if(this.readyState!==4) return;
                var name1=this.responseXML.documentElement.getElementsByTagName("username")[0].innerHTML;
                var age1=this.responseXML.documentElement.getElementsByTagName("age")[0].innerHTML;
                console.log(name1+":"+age1);//张三:23
            }
        </script>
    • JSON也是一种数据描述手段,类似于JavaScript字面量方式,服务端采用JSON格式返回数据,客户端按照JSON格式解析数据
    [
        { "username" : "张三", "age" : 23},
        { "username" : "李四", "age" : 24}
    ]
    <script>
            var xhr=new XMLHttpRequest();
            xhr.open('GET','user.json');
            xhr.send();
            xhr.onreadystatechange=function(){
                if(this.readyState!==4) return;
                var obj=JSON.parse(this.responseText);
                var name2=obj[1].username;
                var age2=obj[1].age;
                console.log(name2+":"+age2);//李四:24
            }
        </script>
    • 不管服务端采用的是XML格式的数据还是JSON格式的数据,本质上都是将数据返回给客户端
    • 服务端应该设置一个合理的Content-Type

    五、其他

    ①response获取到的结果会根据responseType的变化而变化,而responseText永远获取的都是字符串形式的响应体

    <script>
           var xhr=new XMLHttpRequest();
           xhr.open('GET','test.php');
           xhr.send();
           //responseType还允许作者将响应类型更改为一个"arraybuffer", "blob", "document", "json", 或 "text" 。
           //如果将一个空字符串设置为responseType的值,则将其假定为类型“text”,即 "" 等效于 "text";
           //兼容性不是很好,推荐使用responseText
           xhr.responseType='';
           xhr.onreadystatechange=function(){
               if(this.readyState!==4) return;
               console.log(this.response);
           }
        </script>

    ②兼容方案:XMLHttpReuquest在老版本浏览器(IE5/6)中有兼容问题,可以通过另外一种方式代替

     //兼容IE5/6
            var xhr=window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHttp");

    ③补充:Chrome中控制台展开被打印的对象时,会访问即时的数据

    <script>
            var obj={foo:123};
            console.log(obj);
            setTimeout(function(){
                obj.foo=456;
                console.log(obj);
            },3000)
            //说明:
            //打开控制台,如果先打开{foo: 123},还未出现{foo: 456},看到的前面foo的值是123,后面foo的值是456;
            //打开控制台,如果{foo: 123}和{foo: 456}都已经显示,打开任何一个看到的值都是456
        </script>
  • 相关阅读:
    eclipse中不能找到dubbo.xsd
    CentOS7部署tomcat
    mybatis中的foreach
    mybatis中批量添加orcale
    mybatis中的like使用方式
    mybatis默认参数_parameter和_databaseId
    mybatis中的resultMap
    mybatis操作oracle,插入null值时报错 with jdbctype OTHER
    mybatis 中 #{} 和 ${} 的区别
    mybatis Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [0, 1, param1, param2]
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9222494.html
Copyright © 2011-2022 走看看