11-Ajax详解

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
五步使用法:
  • 1.创建异步对象:var ajaxObj = new XMLHttpRequest();
  • 2.使用open方法设置请求的参数:
    • ajaxObj.open('get','xxx.php');
    • 参数1为请求的方法,参数2为请求的url;
  • 3.发送请求:(发送请求报文)
    • ajaxObj.send();
  • 4.注册事件:(服务器返回响应报文)
    • 状态改变时就会调用,如果要在数据完成请求回来的时候才调用,我们需要手动的写一些判断的逻辑;
ajaxObj.onreadystatechange = function (){
        //为了保证数据完整回来,我们一般会判断两个值
        if (ajaxObj.readyState==4 && ajaxObj.status==200){
            //在注册事件中,获取返回的内容,并修改页面的显示
        }
}
  • 5.在注册的事件中,获取返回的内容,并修改页面的显示。


    浏览器与服务器的关系
  • 示例代码: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.近期电影展示。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,389评论 25 707
  • 放暑假了我们决定去王奶奶家住两天,王奶奶家位于渑池县东北部偏远的小山村。 爸爸带上妈妈,奶奶、王奶奶、弟弟和妹...
    07小石头奥特曼阅读 496评论 8 4
  • 虽然新家是北欧风格 但我们的心里一直有着 爱国情怀 中式风格也是我们的心头好 说不定等以后有钱了 等我们年老了 我...
    PWong阅读 247评论 0 0
  • 冬天时用reveal还是1.X版本。这周发现已经出来reveal 4了,用原来的方法配置已经失效了。书归正传: s...
    知行合一认知升级阅读 2,220评论 2 27