• WEB前端第六十二课——自封装Ajax、跨域、分页


    1.Ajax封装方法

      自封装Ajax请求文件,其实就是将原生的Ajax的请求代码抽象为一个函数,

      然后单独生成一个js文件保存,用到Ajax的时候引入文件,调用函数的过程。

      封装Ajax大致步骤如下:

        ⑴ 提供创建xhr对象的兼容性函数

        ⑵ 提供发送请求的对外接口

        ⑶ 设计并约定对外接口的参数规格

        ⑷ 实现对外接口中参数处理

        ⑸ 实现对外接口中相应处理

        ⑹ 实现对外接口中发送处理

        ⑺ 设置命名空间,避免全局变量污染

    2.Ajax封装实现

      代码示例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自封装Ajax测试</title>
        <script src="privyAjaxUnit.js"></script>
    </head>
    <body>
        <button>发送测试</button>
        <script>
            var btn=document.querySelector('button');
            btn.onclick=function () {
                myAjax({
                    type:'post',
                    url:'privyAjax.php',
                    data:{
                        uName:'Rebecca',
                        uCode:'111111'
                    },
                    success:function (res) {
                        console.log(res);
                    }
                });
            }
        </script>
    </body>
    </html>
    
    //模拟jQ中的Ajax创建myAjax方法,
    function myAjax(paramsObj) {
        //判断参数对象中的请求方式,请求方式为“get”时
        if (paramsObj.type.toLowerCase()=='get'){
            var arr=[];
            for (var ki in paramsObj.data){
                //paramsObj.data为对象类型数据,通过for in方法将其转为数组
                var str=ki+'='+paramsObj.data[ki];
                arr.push(str);
            }
            //   由于get方法传参需要是字符串格式,通过join方法将数组转为字符串,并使用“&”拼接。
            var paramStr=arr.join('&');
    
            //   将字符串格式的参数拼接到“url”,但拼接之前有必要判断一下调用Ajax时,
            //   url是否已有部分参数或传参符号“?”,通过三目运算使用indexof方法遍历查找“?”。
            paramsObj.url+=paramsObj.url.indexOf('?')==-1?'?'+paramStr:'&'+paramStr;
    
            //   判断参数对象中的请求方式,请求方式为“post”时
        }else if (paramsObj.type.toLowerCase()=='post'){
            var formData=new FormData();
            for (var ki in paramsObj.data){
                formData.append(ki,paramsObj.data[ki]);
            }
        }else{
            console.log('无该种请求方式!')
        }
    //    创建xhr对象
        var xhr=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('');
        xhr.onreadystatechange=function () {
            if (xhr.readyState==4){
                if (xhr.status==200){
                    //调用回调函数,并将后台返回的数据解析后传参。
                    paramsObj.success(JSON.parse(xhr.responseText));
                }
            }
        }
    //    准备发送请求
        xhr.open(paramsObj.type, paramsObj.url, true);
    //    发送请求
        if (paramsObj.type.toLowerCase()=='get'){
            xhr.send(null);
        }else if (paramsObj.type.toLowerCase()=='post'){
            xhr.send(formData);
        }else {
            console.log('无该种请求方式,请求发送失败!')
        }
    }
    /*自封装Ajax函数的创建过程,本质就是以参数化的形式实现原生Ajax请求,
    上述代码中从第4行到第26行,都是为了判断请求方式,进而根据不同的请求方式生成“url”或“ForMData”*/
    
    //myAjax方法创建完成后,可以将其封装到“(function(){}())”这个自执行函数中,
    /*(function (){
        function myAjax(paramsObj) {...}
    //   可以将创建好的myAjax方法绑定到“window”对象,通过window调用
        window.myAjax=myAjax;
    }());*/
    <?php
        $suc=array('msg'=>'ok');
        if($_POST){
            $suc['info']=$_POST;
        }else if($_GET){
            $suc['info']=$_GET;
        }else{
            $suc['info']='无此种请求方式';
        };
        echo json_encode($suc);
    ?>
    

    3.跨域

      所谓跨域,是指前台访问路径不符合同源政策时即为跨域。

      同源政策,是两个路径是否在同一台服务器下的判断标准。

      判断标准,三要素(网络协议、主域名或IP、端口号)相同则视为同一台服务器,否则反之。

      Ajax不能发送跨域请求,出现跨域时会报错。

      解决Ajax跨域问题两种常用方法:

        ⑴ 通过后台请求跨域文件解决,后台不存在跨域问题;

          PHP中访问跨域url路径,使用“file_get_contents('跨域url')”方法

          后台获取跨域文件后,前台再使用Ajax方法获取后台数据

        ⑵ 使用“jsonp”通过前台解决。

          jsonp解决方案不使用Ajax方法,而是使用其它既具有前后台交互、请求异步以及

          链接PHP后台这三个核心功能,又可以访问外部文件的标签替代Ajax。

           <script>标签满足上述条件,但需要后台配合实现跨域请求。

        代码示例:

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>跨域请求</title>
    </head>
    <body>
        <button onclick="creatScript()">跨域请求</button>
    <script>
    //  第一种方式:通过创建script元素发送请求
        /*function creatScript() {
            var script=document.createElement('script');
            script.src='crossServ.php';
            document.body.appendChild(script);
            script.onload=function(){
                this.remove();
            }
        }*/
        function cross(res) {
            console.log(res);
        }
    </script>
    <!--  第二种方式:直接在<script>标签中定义 src 属性值  -->
    <!--  为确保后台返回数据时调用的方法与前台定义方法一致,在发送请求时可将方法名一并发送  -->
        <script src="crossServ.php?callback=cross"></script>
    </body>
    </html>
    
    <?php
    //  通过前台 callback 参数接收方法名。
        $fn=isset($_GET['callback'])?$_GET['callback']:'cross';
        $info=file_get_contents('http://blog.sina.com.cn');
        $info=json_encode($info);
        echo "{$fn}({$info})";
    ?>
    

    4.分页案例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>multi-pages</title>
        <script src="../JScodeFile/jquery-1.8.3.js"></script>
        <style>
            .contentUl{
                 600px;
                margin: 50px auto;
            }
            .contentUl li{
            }
            .btnContainer{
                height: 30px;
                margin: 20px auto;
            }
            .btnContainer span{
                border: 1px solid grey;
                box-shadow: 0 1px 2px #0f6674;
                margin: 0 3px;
                padding: 0 5px;
                cursor: pointer;
            }
            .btnContainer span.active{
                border: none;
                box-shadow: none;
                color: orangered;
                font-weight: bold;
            }
        </style>
    </head>
    <body>
        <ul class="contentUl" id="contentUl"></ul>
        <div class="btnContainer"></div>
        <script>
            var contentUl=document.querySelector('#contentUl');
            var btnContainer=document.querySelector('.btnContainer');
            $.get('multiPages.php',function (data) {
                var content=JSON.parse(data);   //获取后台数据
            //  定义页码索引
                var rows=5;
                var rowsNum=content.length;
                var pagesNum=Math.ceil(content.length/rows);
                var activePageNum=1;        //默认加载第一页。
    
                //创建分页索引
                $('<span>上一页</span>').appendTo(btnContainer);
                for (var j=1;j<=pagesNum;j++){
                    $('<span>'+j+'</span>').appendTo(btnContainer);
                }
                $('<span>下一页</span>').appendTo(btnContainer);
                $('.btnContainer span').eq(1).addClass('active');
    
                //  定义分页内容
                function turnPage(activePageNum){
                    var rowsIndex=rows*activePageNum;
                    if (rowsIndex>rowsNum){
                        rowsIndex=rowsNum;
                    }
                    //每次生成页面内容前对列表进行清空操作,否则会造成内容累加!
                    $('#contentUl').empty();    //empty()为jQ方法,JS变量无法调用
                    for (var i=rows*(activePageNum-1);i<rowsIndex;i++){
                        $('<li>'+content[i]["author"]+':<br>'+content[i]["summary"]+'<li>').appendTo(contentUl);
                    }
                }
                turnPage(activePageNum)
                
                //定义分页敲击事件
                $('.btnContainer span').click(function () {
    
                    var clickPageNum=$(this).html();
                    if (clickPageNum=='上一页'){
                        activePageNum--;
                        if (activePageNum<1){
                            activePageNum=1;
                            return;
                        }
                    }else if (clickPageNum=='下一页'){
                        activePageNum++;
                        if (activePageNum>pagesNum){
                            activePageNum=pagesNum;
                            return;
                        }
                    }else {
                        activePageNum=clickPageNum;
                    }
                    //点击翻页时清除其他兄弟元素的“active”属性。
                    $('.btnContainer span').eq(activePageNum).addClass('active').siblings().removeClass('active');
                    turnPage(activePageNum);
                });
            });
        </script>
    </body>
    </html>
    
    <?php
        $dbBase=new PDO('mysql:host=localhost;dbname=dbTest;charset=utf8','root','');
        $res=$dbBase->query('select * from news where 1');
        if($res){
            $data=$res->fetchAll(PDO::FETCH_ASSOC);
            echo json_encode($data);
        }else{
            echo '没有数据!';
        }
    ?>
    

      

      

      

  • 相关阅读:
    c#实现windows远程桌面连接程序
    基于.NET平台常用的框架整理
    c#无限循环线程如何正确退出
    c# 内存的具体表现- 通用类型系统 深拷贝 浅拷贝 函数传参
    coco2d-x convertToWorldSpace介绍
    Effective C++条款20:宁以pass-by-reference-to-const替换pass-by-value。Test code
    函数指针与指针函数返回值的区别
    游戏开发那些事
    lua 根据指定字符拆分table字符串(转载)
    实习和学习的双重压力
  • 原文地址:https://www.cnblogs.com/husa/p/14332127.html
Copyright © 2020-2023  润新知