美文网首页
11-Ajax详解

11-Ajax详解

作者: magic_pill | 来源:发表于2017-09-08 16:58 被阅读153次

    Ajax的基本概念及使用

    同步&异步

    • 同步:必须等待前面的任务完成,才能继续后面的任务;
    • 异步:不受当前主要任务的影响。
    • 举个例子:
    • 同步:我们在银行排队时,只有等到你了,才能够去处理业务;
    • 异步:我们在排队的时候,玩王者农药的先后顺序是各不相关的。

    异步更新网站

    • 当我们访问一个普通的网站时,当浏览器加载完:HTML、CSS、JS以后网站的内容就固定了。如果网站内容发生更改必须刷新页面才能够看到更新的内容。

    • 网站内容更新:常规的网站内容更新,必须通过刷新才能显示新内容。

    • 异步更新:

    • 我们在访问新浪微博时,当你看到一大半了,会自动帮我们加载更多的微博,同时之前的页面并没有刷新。

    Ajax概念

    • 在不刷新页面的情况下,“偷偷”的发送数据给服务器,通过发出http请求。

    • 在没有学习Ajax以前,如果想要发出http请求(发出请求报文):

    • 页面会刷新;

    • 后果:如果网速很慢,刷新页面势必会重新加载;造成不必要的时间浪费;

    • 一些极少量的信息想要提交给服务器,也没有必要刷新整个页面。

    • 写法:是通过js在浏览器端帮我们预定义的一个异步对象来完成的。

    • 事例:当我们正在排队的时候,可以通过手机去干一些其他的事情。

    • 在浏览器中,我们也能够不刷新页面,通过ajax的方式去获取一些新的内容,类似网页有微博、朋友圈、邮箱等。

    • 单词解释:Asynchronous Javascript And XML(异步JavaScript和XML),他并不是凭空出现的新技术,而是对于现有技术的结合:核心是js对象XMLHttpRequest

    XMLHttpRequest

    • ajax使用的依旧是HTTP请求,那么让我们来回忆一下一个完整的HTTP请求需要什么:
    • 请求的网址,方法get/post;
    • 提交请求内容数据、请求主体等;
    • 接收响应回来的内容。
    写Ajax的步骤
    • 先写html页面,通过某种条件发出ajax请求;
    • 写在php页面,处理发过来的请求;
    • 再回到浏览器异步对象的onreadystatechange事件中,去处理返回的内容。
    发送Ajax请求,使用的是js
    • 五步使用法:
    • 创建异步对象:var ajaxObj = new XMLHttpRequest();
    • 使用open方法设置请求的参数:
      • ajaxObj.open('get','xxx.php');
      • 参数1为请求的方法,参数2为请求的url;
    • 发送请求:(发送请求报文)
      • ajaxObj.send();
    • 注册事件:(服务器返回响应报文)
      • 状态改变时就会调用,如果要在数据完成请求回来的时候才调用,我们需要手动的写一些判断的逻辑;
    ajaxObj.onreadystatechange = function (){
            //为了保证数据完整回来,我们一般会判断两个值
            if (ajaxObj.readyState==4 && ajaxObj.status==200){
                //在注册事件中,获取返回的内容,并修改页面的显示
            }
    }
    
    • 在注册的事件中,获取返回的内容,并修改页面的显示。


      浏览器与服务器的关系
    • 示例代码:GET(get的数据,直接在请求的url中添加即可)
    • html中的代码:
    <body>
        <input type="text" class="user">
        <button>发送请求</button>
        <script>
            document.querySelector("button").onclick = function () {
                //1.创建异步对象
                var xhr = new XMLHttpRequest();
    
                //2.设置method、url等参数
                var userName = document.querySelector(".user").value;
                xhr.open("get","03-XMLHttpRequest.php?name="+userName);
    
                //3.发送数据
                xhr.send();
    
                //4.绑定事件
                xhr.onreadystatechange = function () {
                    if (xhr.readyState==4 && xhr.status==200){
                        //5.在绑定事件中获取返回的数据,显示页面
                        console.log(xhr.responseText);
                    }
                }
            }
        </script>
    </body>
    
    • php中的代码:
    <?php
            echo $_GET['name'].",欢迎你";
    ?>
    
    • 示例代码:POST
    • 有两点不同
      1.发送的数据写在send方法中;
      2.必须要在open和send之间添加setRequestHeader("Content-type","application/x-www-form-urlencoded");
    • html中的代码:
    <body>
        <input type="text" class="user">
        <button>发送请求</button>
        <script>
            document.querySelector("button").onclick = function () {
                //1.创建异步对象
                var xhr = new XMLHttpRequest();
    
                //2.设置method、url等参数
                xhr.open("POST","03-XMLHttpRequest.php");
    
                //如果使用post发送数据,必须要添加如下内容,修改发送给服务器的请求报文的内容。form表单使用post发送数据不需要设置,因为form表单默认会进行转换
                xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    
                //3.发送请求,发送请求的数据写在send方法中
                //格式 name=jiang & age=18
                var userName = document.querySelector(".user").value;
                xhr.send("name="+userName);
    
                //4.绑定事件
                xhr.onreadystatechange = function () {
                    //5.在绑定事件里获取数据,展示页面
                    if (xhr.readyState==4 && xhr.status==200){
                        console.log(xhr.responseText);
                    }
                }
            }
        </script>
    </body>
    
    • php中的代码:
    <?php
            echo $_POST["name"].",你好";
    ?>
    
    • 实际开发中,get和post的选取:
      由后台程序员以文档或者口头形式告知;
      如果不考虑提交文件,那么get/post的作用基本一致,只是写法不同;
      自己写demo的时候,随便选取哪一个使用。
    练习:异步切换明星头像

    XMLHttpRequest_API讲解

    创建XMLHttpRequest对象(兼容性写法):

    • 新版本浏览器:
    var xml=new XMLHttpRequest();
    
    • IE5和IE6:
    var xml=new ActiveXObject("Microsoft.XMLHTTP");
    
    • 考虑兼容性创建Ajax对象
    var request ;
    if(XMLHttpRequest){
            // 新式浏览器写法
            request = new XMLHttpRequest();
    }else{
            //IE5,IE6写法
            request = new ActiveXObject("Microsoft.XMLHTTP");
    }
    

    发送请求:

    方法 描述
    open(method,url,async) 规定请求的类型、URL 以及是否异步处理请求。<ul><li>method:请求的类型;GET 或 POST;</li><li>url:文件在服务器上的位置;</li><li>async:true(异步)或 false(同步)</li></ul>
    send(string) 将请求发送到服务器。string:仅用于 POST 请求

    POST请求注意点:

    • 如果想要像form表单提交数据那样使用POST请求,需要使用XMLHttpRequest对象setRequestHeader()方法来添加HTTP头。然后在send()方法中添加想要发送的数据:
    xmlhttp.open("POST","ajax_test.php",true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send("fname=Bill&lname=Gates");
    

    onreadystatechange事件

    • 当服务器给予我们反馈时,我们需要实现一些逻辑
    属性 描述
    onreadystatechange 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
    readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化:<ul><li>0:请求未初始化;</li><li>1:服务器连接已建立;</li><li>2:请求已接收;</li><li>3:请求处理中;</li><li>4:请求已完成,且响应已就绪。</li></ul>
    status 200: "OK";404: 未找到页面

    服务器响应内容

    • 如果响应的是普通字符串,使用responseText,如果响应的是XML,使用responseXML
    属性 描述
    responseText 获得字符串形式的响应数据。
    responseXML 获得 XML 形式的响应数据。
    服务器
    • Apache;
    • web服务端开发的语言;
    • 设置访问的网站:
    • 设置网站根目录;
    • 往网站的目录中拷贝文件即可:
      • .html:如果存在该页面,会原封不动的返回给用户;
      • .php:会将php中的代码执行完,将结果返回给浏览器。

    php如何读取文本数据

    • 目的:实现数据和逻辑代码分离;
    • PHP之所以被称为“最好的编程语言”:使用十分方便,基本上我们能够想到的功能,都帮我们封装成了方法:
    file_get_contents(文件路径);
    

    Ajax数据传输XML

    XML简介

    • XML:指可扩展标记语言EXtensible Markup Language,他设计的时候是用来传递数据的,虽然格式跟HTML类似.。
    • xml示例:下面是一个XML示例
    <?xml version="1.0" encoding="UTF-8"?>
    <singer>
    <name>周杰伦</name>
    <age>18</age>
    <skill>途牛</skill>
    </singer>
    
    • XML是纯文本,这点跟HTML很像,所以我们可以用任何的文本编辑软件去打开编辑它。

    XML语法

    • 虽然看起来跟HTML类似,但是XML的语法有些需要注意的,更为详细的可以查阅:http://www.w3school.com.cn/xml/index.asp
    • XML声明:第一行是XML的声明,指定XML版本(1.0)以及使用的编码(UTF-8万国码):
    <?xml version="1.0" encoding="UTF-8"?>
    
    • 自定义标签,XML中没有默认的标签,所有的标签都是我们自定义的;
    • 注:不要使用数字开头,不要使用中文。
    <!-- 下列标签都是被允许的 -->
    <fox></fox>
    <name></name>
    
    • 双标签XML中没有单标签,都是双标签
    <haha>标签内</haha>
    
    • 根节点:XML中必须有一个根节点,所有的子节点都放置在根节点下
    <root>
      <name></name>
    </root>
    
    • XML属性:跟HTML一样,XML的标签里面也能够添加属性type = 'text',但是不建议这样用,而是使用标签的方式来表述内容(下半部分代码)
    <!-- 使用属性配合标签表述信息 -->
    <person sex="female">
      <firstname>Anna</firstname>
      <lastname>Smith</lastname>
    </person>
    <!-- 使用标签来表述信息 -->
    <person>
      <sex>female</sex>
      <firstname>Anna</firstname>
      <lastname>Smith</lastname>
    </person>
    

    XML解析

    • 因为XML就是标签,所以直接用解析Dom元素的方法解析即可;
    • html代码:
    <!DOCTYPE html>
    <html lang="en">
    <head>
          <meta charset="UTF-8">
          <title>Document</title>
    </head>
    <body>
          <person id='personXML'>
              <name>fox</name>
              <age>18</age>
              <skill>小花花</skill>
          </person>
    </body>
    </html>
    
    • 获取方法:
    <script type="text/javascript">
        var xmlObj = document.getElementById("personXML");
        var name = xmlObj.getElementsByTagName('name')[0].innerHTML;
        console.log(name);
    </script>
    

    PHP中设置Header

    • 在php中如果要使用xml传输数据,需要使用header()设置返回的内容为xml:
    header('content-type:text/xml;charset=utf-8');
    
    • 从php中获取xml内容,html中的代码如下:
    <script type="text/javascript">
        document.querySelector('#getXML').onclick = function () {
            var ajax = new XMLHttpRequest();
    
            ajax.open('get','get_XMl.php');
    
            ajax.send();
    
            ajax.onreadystatechange = function () {
                if (ajax.readyState == 4 && ajax.status==200) {
                    // 如果 返回的是 xml文件
                    console.log(ajax.responseText);
    
                    // 异步 对象中 有另外一个属性 用来专门获取 xml
                    // xml对象 在浏览器端 就是一个 document对象
                    // 解析时 可以直接使用 querySelector 或者 getElementById等 document对象 有的语法
                    console.log(ajax.responseXML);
                    console.log(ajax.responseXML.querySelector('name').innerHTML);
                    // 下面这个 页面文档对象,和ajax.responseXML一模一样, 如果要获取某个标签,使用同样的方法
                    console.log(window.document);
                }
            }
        }
    </script>
    
    • php:
    <?php
            header('content-type:text/xml;charset=utf-8');
            $text = file_get_contents("01-getFile-xml.xml");
            echo $text;
    ?>
    
    • xml:
    <?xml version="1.0" encoding="UTF-8" ?>
    <yijiang>
            <name>yijiang</name>
            <age>20</age>
            <sex>男</sex>
    </yijiang>
    
    Ajax中获取xml:
    • 浏览器:

    • 通过xhr.responseXML获取返回的xml值;

    • (如果通过xhr.responseText获取,返回的是字符串)。

    • 服务器:

    • 准备一个xml文件;

    • php中获取xml文件内容,并返回(注意要设置header:header('content-type:text/xml;charset=utf-8');

    实际开发中xml用的频率不是很高,敲两遍就可以了。
    案例:重写明星头像
    • html中:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>change</title>
    
        <style>
            table{
                width: 400px;
                margin: 20px auto;
                border: 1px solid #000;
            }
            td{
                border: 1px solid #000;
            }
            img{
                height: 200px;
                width: 200px;
            }
        </style>
    </head>
    <body>
        <script>
            //1.
            var xhr = new XMLHttpRequest();
            //2.
            xhr.open("get","change-xml.php");
            //3.
            xhr.send();
            //4.
            xhr.onreadystatechange = function () {
                //5.
                if (xhr.readyState==4 && xhr.status==200){
                    var responseStars = xhr.responseXML;
                    var stars = responseStars.querySelector("stars").children;
                    console.log(stars[0].querySelector("name").innerHTML);
                    var str = "<table>";
                    for(var i=0; i<stars.length; i++){
                        str += "<tr>";
                        str += "<td>"+stars[i].querySelector("name").innerHTML+"</td>";
                        str += "<td>![]("+stars[i].querySelector("pic").innerHTML+")</td>";
                        str += "<td>"+stars[i].querySelector("description").innerHTML+"</td>";
                    }
                    str += "</table>";
    
                    document.body.innerHTML = str;
                }
            }
        </script>
    </body>
    </html>
    
    • php中:
    <?php
        header('content-type:text/xml;charset=utf-8');
        echo file_get_contents('change-xml.xml');
    ?>
    
    • xml中:
    <?xml version="1.0" encoding="UTF-8" ?>
    <stars>
        <star>
            <name>Angelababy</name>
            <age>30</age>
            <description>著名女演员</description>
            <pic>images/baby.jpg</pic>
        </star>
        <star>
            <name>mage</name>
            <age>16</age>
            <description>国际名模</description>
            <pic>images/mage.jpeg</pic>
        </star>
        <star>
            <name>wangge</name>
            <age>18</age>
            <description>大陆著名企业家</description>
            <pic>images/shuaige.jpeg</pic>
        </star>
    </stars>
    

    Ajax传输JSON

    JSON语法

    • JSON(JavaScript Object Notation)
      一种字符串格式;
      是ECMAScript的子集,作用是进行数据的交换;
      而且由于语法更为简洁,网络传输以及机器解析都更为迅速;
      使用的最多,基本上所有的语言都有将JSON字符串转化为该语言对象的语法。

    • 语法规则:

    • 数据在键值对中;

    • 数据由逗号分隔;

    • 花括号保存对象;

    • 方括号保存数组;

    • 总结:属性名必须使用双引号包裹,属性值(数组除外)必须使用双引号包裹。

    • 数据类型:

    • 下列内容,无论是键还是值 都是用双引号包起来:

      • 数字(整数或浮点数);
      • 字符串(在双引号中);
      • 逻辑值(true 或 false);
      • 数组(在方括号中);
      • 对象(在花括号中);
      • null。
    • 示例代码:下部分代码看起来类似于定义JavaScript对象

    // 基本对象
    {
          "name":"fox",
          "age":"18",
          "sex":"true",
          "car":null
    }
    // 数组
    [
          {
              "name":"小小胡",
              "age":"1"
          },
          {
              "name":"小二胡",
              "age":"2"
          }
    ]
    

    JSON解析

    • 接下来演示如何使用JavaScriptPHPJSON进行解析

    • 基本使用步骤:

    JSON图

    JavaScript中
    • 使用JSON对象:
    • JSON.parse()方法:将JSON字符串转化为JavaScript对象
    • JSON.stringify()方法:将JavaScript对象转化为JSON字符串
    • 由于老式IE(8以下)浏览器中没有JSON对象,通过导入JSON2.js框架即可解决,框架获取地址为:JSON2.js_github地址(https://github.com/douglascrockford/JSON-js);
    var Obj = {
      name:"fox",
      age:18,
      skill:"撩妹"
    };
    console.log(Obj);
    // 将JavaScript对象格式化为JSON字符串
    var jsonStr = JSON.stringify(Obj);
    console.log(jsonStr);
    // 将JSON字符串转化为JavaScript对象
    var jsonObj = JSON.parse(jsonStr);
    console.log(jsonObj);
    
    • 使用eval()方法:使用eval()方法需要注意的是,需要将内容使用()括号包裹起来,如示例代码:
    <script type="text/javascript">
    var jsonStr ={
      "name":"fox",
      "age":18,
      "skill":"撩妹"
    };
    
    var jsonObj = eval('('+jsonStr+')'); console.log(jsonObj);
    
    </script>
    
    PHP中
    • json_decode()方法:

    • json字符串转化为php变量

    • json_encode()方法:

    • php变量转化为json字符串

    • 示例代码:

    <?php
        header("Content-Type:text/html;charset=utf-8");
        // json字符串
        $jsonStr = '{"name":"yijiang","age":"18","skill":"歌神"}';
        // 字符串转化为 php对象
          print_r(json_decode($jsonStr));
    
          echo "<br>";
          // php数组
          $arrayName = array('name' =>'littleFox' ,'age' => 13 );
          // php对象 转化为 json字符串
          print_r(json_encode($arrayName));
     ?>
    
    • 输出结果为:
    stdClass Object ( [name] => yijiang [age] => 18 [skill] => 歌神 )
    {"name":"littleFox","age":13}
    
    解析JSON的完整写法:
    • html中:此时js中获取返回的数据使用xhr.responseText
        <script>
            //1.
            var xhr = new XMLHttpRequest();
            //2.
            xhr.open("post","02-getFile-json.php");
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            //3.
            xhr.send();
            //4.
            xhr.onreadystatechange = function () {
                //5.
                if (xhr.readyState==4 && xhr.status==200){
                    var person = JSON.parse(xhr.responseText);
                    console.log(person);
                    //Object {name: "jiang", age: "16", skill: "撩汉"}
                    console.log(person.name);   //jiang
                    console.log(person.age);    //16
                }
            }
        </script>
    
    • php中:
    <?php
        echo file_get_contents("02-getFile-json.json");
    ?>
    
    • json文件:
    {
        "name":"jiang",
        "age":"16",
        "skill":"撩汉"
    }
    

    Ajax工具函数封装

    原生Ajax写法

    • 原生使用Ajax主要分为五步,需要手写较多内容,如果每次我们使用Ajax都需要手写一遍,较为浪费时间,所以我们将公共代码抽取,封装为工具函数。

    • 五步使用法:

    • 建立XMLHTTPRequest对象

    • 使用open方法设置和服务器端交互的基本信息:

      • 设置提交的网址、数据以及post提交的一些额外内容;
    • 使用send设置发送的数据,开始和服务器端交互:

      • 发送数据;
    • 注册事件:

      • 当服务器回应我们了,我们想要执行什么逻辑;
    • 更新界面:

      • 在注册的事件中,获取返回的数据,更新界面。
    • 示例代码:GET:

    • get的数据,直接在请求的url中添加即可;

    <script type="text/javascript">
      // 创建XMLHttpRequest 对象
      var xml = new XMLHttpRequest();
      // 设置跟服务端交互的信息
      xml.open('get','01.ajax.php?name=fox');
      //发送数据
      xml.send(null);    // get请求这里写null即可,或者直接空
      // 接收服务器反馈
      xhr.onreadystatechange = function () {
          // 这步为判断服务器是否正确响应
          if (xhr.readyState == 4 && xhr.status == 200) {
              // 打印响应内容
              alert(xml.responseText);
          }
      };
    </script>
    
    • 示例代码:POST:
    <script type="text/javascript">
      // 异步对象
      var xhr = new XMLHttpRequest();
    
      // 设置属性
      xhr.open('post', '02.post.php' );
    
      // 如果想要使用post提交数据,必须添加
      xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    
      // 将数据通过send方法传递
      xhr.send('name=fox&age=18');
    
      // 发送并接受返回值
      xhr.onreadystatechange = function () {
          // 这步为判断服务器是否正确响应
          if (xhr.readyState == 4 && xhr.status == 200) {
                 alert(xhr.responseText);
          }
      };
    </script>
    

    抽取公共部分

    • 重复步骤分析:

    • 创建异步对象;

    • 异步对象open,send方法调用;

    • post方法需要添加HTTP协议头文件;

    • 判断Ajax响应状态。

    • 哪些部分是需要使用者自定义的:
      1. 提交方法;
      2. url地址;
      3. 数据;
      4. Ajax请求成功调用方法;
      上述内容,应该是调用时,由用户传入的。

    //优化,传入一个对象作为参数,对象中分别包含其它属性:method,url,data,success
    function ajax_tool(params) {
        //1.创建异步对象
        var xhr = new XMLHttpRequest();
        //2.3.
        if (params.method == "get"){
            if (params.data){
                params.url += "?";
                params.url += params.data;
            }
            //2.设置方法和url等
            xhr.open(params.method,params.url);
            //3.直接发送数据
            xhr.send();
        }else {
            //2.
            xhr.open(params.method,params.url);
            //设置请求头
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            if (params.data){
                //3.如果有数据,就发送数据
                xhr.send(params.data);
            }else {
                //如果没有数据直接发送就好
                xhr.send();
            }
        }
        //4.注册事件
        xhr.onreadystatechange = function () {
            //5.在事件中获取数据,并修改界面
            if (xhr.readyState==4 && xhr.status==200){
                success(xhr.responseText);
            }
        };
    }
    
    案例:聊天机器人

    jQuery中的Ajax

    JQuery中Ajax使用

    $.get()方法

    使用`get`方法取代复杂 $.ajax 向服务器获取数据;
    请求成功时可调用回调函数;
    如果需要在出错时执行函数,请使用 $.ajax。
    
    • 参数列表
    参数 描述
    url 必需。规定将请求发送的哪个 URL。
    data 可选。待发送 Key/value 参数
    success(response) 可选。规定当请求成功时运行的函数。额外的参数:response - 包含来自请求的结果数据。
    dataType 可选。规定预计的服务器响应的数据类型。默认地,jQuery 将智能判断。可能的类型:"xml"、"html"、"text"、"script"、"json"、"jsonp"。
    • 关于dataType的说明:预计从服务端获取的数据类型,可以不写,如果写了,写成json,jq内部会帮我们进行JSON.parse()的转化。注意:

      • 如果写成json,并且服务端返回的就是json格式字符串,在回调函数中获取的实参就是转化完成的js对象,直接按照对象使用即可;
      • 如果写成json,但是返回的不是json格式的数据,那么将会返回null。
    • 使用演示:

    • html代码:

    <script src="jquery.min.js"></script>
    <script>
            $.get("01-jq-get.php",{name:"yijiang",des:"大帅比"},function (data) {
                console.log(data);
            });
    </script>
    
    • php代码:
    <?php
            echo $_GET['name']."是一个".$_GET['des'];
    ?>
    
    • 结果:yijiang是一个大帅比

    $.post方法

    使用 post 请求功能以取代复杂 $.ajax;
    请求成功时可调用回调函数;
    如果需要在出错时执行函数,请使用 $.ajax。
    
    • 参数
    参数 说明
    url 必选。发送请求地址
    data 可选。待发送 Key/value 参数
    callback 可选。发送成功时回调函数
    type 可选。返回内容格式,xml, html, script, json, text, _default。
    • html代码:
    <script src="jquery.min.js"></script>
    <script>
        $.post("02-jq-post.php",{name:"mage",des:"大美妞"},function (data) {
            console.log(data);
        });
    </script>
    
    • php代码:
    <?php
        echo $_POST['name'].'是一个'.$_POST['des'];
    ?>
    
    • 结果:mage是一个大美妞

    $.getJSON方法

    在 jQuery 1.2 中,您可以通过使用JSONP形式的回调函数来加载其他网域的JSON数据:
    如 "myurl?callback=?"。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
    注意:此行以后的代码将在这个回调函数执行前执行。
    
    • 参数:
    参数 说明
    url 必选,发送请求地址。
    data 待发送 Key/value 参数。
    callback 载入成功时回调函数。
    • html中代码:
    <script src="jquery.min.js"></script>
    <script>
        $.getJSON('02-jq-post.php',function (data) {
            console.log(data);
        })
    </script>
    
    • php中代码:
    <?php
        echo file_get_contents('xxx-json.json');
    ?>
    
    • json文件代码:
    {
        "name":"jiang",
        "age":"16",
        "skill":"撩汉"
    }
    
    • 结果:Object {name: "jiang", age: "16", skill: "撩汉"}

    格式化表单$('form').serialize()

    我们在向服务器提交数据时,如果使用的是Ajax需要手动将数据格式化,转化成类似name=fox&age=18这样的格式,jQuery已经帮助我封装好了一个格式化数据的方法。
    
    • 语法:$(selector).serialize() 直接可以将form中拥有name属性的表单元素的字,进行格式化。

    • 示例代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>测试jq_serialize方法</title>
      <script type="text/javascript" src="./files/jquery.min.js"></script>
      <script type="text/javascript">
          $(function(){
              $("#getFormInfo").on("click",function(){
                  var info = $("#testForm").serialize()
                  console.log(info);
              })
          })
      </script>
    </head>
    <body>
      <form id="testForm">
          <input type="text" placeholder="您的姓名" name="userName">
          <input type="text" placeholder="您的爱好" name="userHabbit">
          <input type="text" placeholder="您最喜爱的食物" name="userHabbit">
      </form>
      <input type="button" value="格式化表单数据" id="getFormInfo">
    </body>
    </html>
    
    • 演示效果:userName=yijiang&userHabbit=swimming&userHabbit=meat

    $.ajax({})方法

    $.ajax()方法相比于前面的方法,拥有更为自由的定制性,可以替换$.get(),$.post()方法。
    
    参数 描述
    settings 可选。用于配置 Ajax 请求的键值对集合。可以通过 $.ajaxSetup() 设置任何选项的默认值。
    • 回调函数
      如果要处理$.ajax()得到的数据,则需要使用回调函数。beforeSend、error、dataFilter、success、complete。
      beforeSend:在发送请求之前调用,并且传入一个XMLHttpRequest作为参数。
      error:在请求出错时调用。传入XMLHttpRequest对象,描述错误类型的字符串以及一个异常对象(如果有的话)
      dataFilter:在请求成功之后调用。传入返回的数据以及"dataType"参数的值。并且必须返回新的数据(可能是处理过的)传递给success回调函数。
      success:当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。
      complete:当请求完成之后调用这个函数,无论成功或失败。传入XMLHttpRequest对象,以及一个包含成功或错误代码的字符串。

    • 示例代码:

    • 这里演示的是常用的属性

    $.ajax({
            url:'01.php',   //请求地址
            data:'name=fox&age=18',     //发送的数据
            type:'GET',     //请求的方式
            success:function (argument) {},     // 请求成功执行的方法
            beforeSend:function (argument) {},  // 在发送请求之前调用,可以做一些验证之类的处理
            error:function (argument) {console.log(argument);},   //请求失败调用
    });
    
    案例:注册界面

    模板插件

    模版引擎简介

    • 我们在使用ajax请求数据时,返回的如果是一个JSON格式的字符串,我们需要将其包装到对应的HTML代码中,再添加到页面上,才能看到效果。那么这个包装得过程有没有简单的方法呢?

    • 假设有如下数据(javascript中)

    var obj = {
         name:"fox",
         age:18,
         skill:"卖萌"
    };
    
    • 希望包装为:
    <ul>
      <li>姓名:fox</li>
      <li>年龄:18</li>
      <li>爱好:卖萌</li>
    </ul>
    
    • 定义模板,替换:
    • 其间需要我们使用对象替换的位置为<%= 属性名 %>部分,如果可以:读取模板->传入对象->完成替换->返回html代码 实现这样的步骤,那么就能够完成我们的模板操作了
    <ul>
      <li>姓名:<%= name %></li>
      <li>年龄:<%= age %></li>
      <li>爱好:<%= skill %></li>
    </ul>
    

    模版插件原理

    我们定义一段文本作为模板,读取文本,使用特殊的符号<%= 属性名 %>,通过正则表达式找到这些特殊的符号进行替换,是不是就实现了这样的效果呢?

    • 定义正则表达式:
    • 想要匹配<%= 属性名 %>, 我们可以定义如下正则(javascript中):
    JS中的RegExp对象:
            创建:
                创建方法1: var reg = new RegExp("正则")
                创建方法2: var reg = /正则/;    推荐使用这种
            使用:
                reg.exec(string) 可以检测并返回字符串
    
    正则含义:
            <%:以 <% 开始
            =\s* "="号之后有0个或多个空白字符
            ([^%>]+\S): 匹配除了%>以外的所有字符(至少1个)
            \s*:0个或多个空白字符
            %>:以%>结束
    
    var reg = /<%=\s*([^%>]+\S)\s*%>/;
    

    基本使用

    • 定义好作为模板的文本;
    • 使用正则表达式进行匹配替换即可。
    // 定义文本
    var str = '大家好,我叫<%= name %>,我今年<%= age %>,我的爱好为:<%= skill %>';
    // 定义数据
    var data = {
        name: 'jiang',
        age: 10,
        skill:'打篮球'
    };
    
    // 快速的创建方法,好处,直接使用 \ 即可 不需要考虑 转义
    var reg = /<%=\s*([^%>]+\S)\s*%>/;
    // 返回的是一个对象(数组)
    var match = null;
    
    // 使用  while循环 进行检查,知道没有匹配的内容
    while (match = reg.exec(str)){
        // 匹配到的字符串
        var mathString = match[0]
        // 子表达式匹配到的字符串
        var subString = match[1];
        // 打印文本内容
        console.log("循环中:"+str);
        // 替换字符串的内容
        str = str.replace(mathString,data[subString]);
    }
    console.log("循环完毕:"+str);
    

    ArtTemplate基本使用

    • 模板引擎的用法大同小异,ArtTemplate由于性能优秀,这里我们演示ArtTemplate的用法:
    • 导入模板引擎:将下载好的ArtTemplate导入到页面中:
    <script type="text/javascript" src = "./files/template-native.js"></script>
    
    • 定义模板:
      <% %>:这样的语法是定义逻辑表达式;
      <%=内容 %>:这样的语法为输出表达式;
      注意:这里的模板type='text'如果写成javascript会执行:
    <script type="text" id = "templ01">
            <ul>
                <li><%=name %></li>
                <li><%=age %></li>
                <li><%=skill %></li>
                <li>
                    <ul>favouriteFood
                    <% for(var i = 0 ;i < favouriteFood.length;i++) {%>
                        <li><%=favouriteFood[i] %></li>
                    <% } %>
                    </ul>
                </li>
            </ul>
    </script>
    
    • 定义对象;
    • 调用模板引擎的方法,传入对象,我们可以使用template(模板id,数据);
    // 调用模板引擎的方法
    var backHtml = template("templ01",data);
    // 返回值就是填充好的内容
    
    • 总结:
      1.导入模板对象;
      2.定义模板;一般情况下,模板使用中,type必须写,写成非javascript的内容,若果留空,会默认解析成为js,会报错。
      3.定义对象;
      4.调用模板引擎的方法,传入对象;
      注意点:
      一、如果出现template error错误,一般模板出错,去查找模板:1.for循环写了开头,没有写结尾;2.for循环中的分隔符写成了逗号。
      二、只能接受对象,不能接受数组。

    • 示例:

    <body>
        <script src="template-native.js"></script>
        <script type="text" id="temp">
            <% for(var i=0; i<people.length; i++){ %>
                <ul>
                    <li><%= people[i].name %></li>
                    <li><%= people[i].skill %></li>
                </ul>
            <% } %>
    
        </script>
    
        <script>
            var data = {
                people:[
                    {name: "baby", skill: "演戏"},
                    {name: "yijiang", skill: "负责帅"},
                    {name: "mage", skill: "负责美"}
                ]
            };
            var backHtml = template("temp",data);
            document.write(backHtml);
        </script>
    </body>
    
    使用演示:luowang

    同源以及跨域

    同源

    • 同源策略是浏览器的一种安全策略,所谓同源是指域名协议端口完全相同。
    URL 说明 是否允许通信
    http://www.a.com/a.js
    http://www.a.com/b.js
    同一域名下 允许
    http://www.a.com/lab/a.js
    http://www.a.com/script/b.js
    同一域名下不同文件夹 允许
    http://www.a.com:8000/a.js
    http://www.a.com/b.js
    同一域名,不同端口 不允许
    http://www.a.com/a.js
    https://www.a.com/b.js
    同一域名,不同协议 不允许
    http://www.a.com/a.js
    http://70.32.92.74/b.js
    域名和域名对应ip 不允许
    http://www.a.com/a.js
    http://script.a.com/b.js
    主域相同,子域不同 不允许
    http://www.a.com/a.js
    http://a.com/b.js
    同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
    http://www.cnblogs.com/a.js
    http://www.a.com/b.js
    不同域名 不允许

    跨域方案

    JSONP

    • JSON with Padding其本质是利用了html标签的src属性标签具有可跨域的特性,实现跨域用的是script标签,由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成;
    • 使用script标签,<script src="xxx.php"></script>,默认会发送一个get请求到对应的php页面;
    • 只能以GET方式请求
    • 注意只能够通过get方法;
    • 服务端代码:
    <?php
        // echo "alert('天气不错哦')";
        $callBack = $_GET['callback'];
        $arr = array(
            'name' =>'大帅比' ,
            'color' =>'red'
        );
        echo $callBack."(".json_encode($arr).")";
    ?>
    
    • 前端代码:注意,域名不同
      • 核心是通过script标签src属性提交get请求
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    
        <script type="text/javascript">
            function fn(data){
                 console.log(data);
            }
        </script>
    
        <script type="text/javascript" src='http://www.section02.com/seciton02_jsonP.php?callback=fn'></script>
    </head>
    <body>
        <h1>区域1的页面_jsonP演示</h1>
    </body>
    </html>
    
    • 如果我们定义的fn方法有形参,会将从服务器拿到的括号中的值传递给形参,并且如果传递过来的是json字符串,会自动帮我们转化为js对象。
    jq已经帮我们封装好了jsonp的请求,直接使用即可:
    • dataType预期服务器返回的数据类型为jsonp;
    • "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数;
    • 如果需要给jsonp指定回调函数:通过jsonpCallback为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。
    <script>
        function eatFood() {
            console.log("好好吃哟");
        }
    </script>
    <script src="../03-jq-ajax/jquery.min.js"></script>
    <script >
        $.ajax({
            url:"01-jsonp-script.php",
            dataType:"jsonp",
            callback:eatFood()
        })
    </script>
    

    jQuery 的$.ajax()

    • 方法当中集成了JSONP的实现,可以非常方便的实现跨域数据的访问。

    • dataType: 'jsonp' 设置dataType值为jsonp即开启跨域访问;

    • jsonp可以指定服务端接收的参数的“key”值,默认为callback;

    • jsonpCallback可以指定相应的回调函数,默认自动生成

    • 示例代码:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    
        <script type="text/javascript" src='jquery/jquery-3.0.0.min.js'></script>
    </head>
    
    <body>
    <h1>区域1的页面</h1>
        <input type="button" name="" onclick='sendAjax()' value="jquery区域请求">
    </body>
    
    </html>
    
    <script type="text/javascript">
        function sendAjax(){
            $.ajax({
                url:'http://www.section02.com/sectcion02_jqJsonp.php',
                type:'post',
                dataType: 'jsonp',
                data:{name:'itt'},
                success:function(data){
                    console.log(data);
                }
            })
        }
    </script>
    

    天气预报

    • 一些平台为我们提供了可以直接使用的接口,我们只需要按照他们提供的格式提交数据即可。

    • 百度车联网api:http://developer.baidu.com/map/carapi-7.htm

    • 开发者秘钥ak:0A5bc3c4fb543c8f9bc54b77bc155724

    瀑布流

    什么是瀑布流?

    • 瀑布值得是从上往下流动的水,并且水量也较大,瀑布流指的是内容、信息,像瀑布一样从上往下进行排布。

    • 瀑布流:示例取自:堆糖网:http://www.duitang.com/topics/

    瀑布流实现原理

    • 瀑布流的核心为:

    • 宽度一致,高度参差不齐;

    • 新增行的内容,优先添加到最矮的下方。

    • 难点:

    • 当我们到了新一行时,如何获取上一行高度最小的行高?

    • 可以定义数组用来保存高度,新增了以后替换数组中原始的高度即可。

    • 实现技术:

    • Ajax;

    • jq->Ajax请求;

    • 模板引擎->渲染页面。

    • 知识点:

    • 模板引擎;

    • jqajax请求;

    • php中,字符串和php对象的相互转化;

    • jq插件写法:瀑布流的算法。

    • 补充:

    • 可以直接使用jq对象点出来的语法,除了jq本身,还有jq的插件,这里我们将瀑布流封装成jq插件。

    • jq插件:

      • $.fn.extend,调用:$('xxx').fun;
      • $.extend,调用:$.fun;
      • 注:这里的fun跟我们定义的时候写的属性名一致;
      • jq插件命名一般建议使用jQuery.插件名.js格式;
      • 插件中的方法名建议和插件名一致。
    // 为 jq 添加 插件
    // 注册完毕以后 使用 $("xxx").fun 使用
    $.fn.extend({
        study:function () {
            console.log('我要好好学习了哟');
            // 在这个方法中 我们可以使用 $('选择器')获取到jq对象
            // this 就是我们获取到的jq对象
            // 注意:容易搞混 jq对象跟dom对象 所以这里建议使用以$开头的this替代
            // 一看到 $_开头的,就知道是jq对象,防止跟dom对象弄混
            var $_this = this;
            $_this.css({backgroundColor:'yellow'});
            // jq有一个特点是 链式编程
            // 为了能够链式编程 建议 return 当前使用的jq对象
            return $_this;
        }
    });
    // 注册完毕以后 使用$.fun 使用
    $.extend({
        play:function(){
            console.log('我要玩游戏了哟');
        }
    })
    
    案例:(百度开发平台)
    • 1.天气展示;
    • 2.近期电影展示。

    相关文章

      网友评论

          本文标题:11-Ajax详解

          本文链接:https://www.haomeiwen.com/subject/yocnjxtx.html