11-Ajax详解

2017-09-08  本文已影响153人  magic_pill

Ajax的基本概念及使用

同步&异步

异步更新网站

Ajax概念

XMLHttpRequest

写Ajax的步骤
发送Ajax请求,使用的是js
ajaxObj.onreadystatechange = function (){
        //为了保证数据完整回来,我们一般会判断两个值
        if (ajaxObj.readyState==4 && ajaxObj.status==200){
            //在注册事件中,获取返回的内容,并修改页面的显示
        }
}
<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
        echo $_GET['name'].",欢迎你";
?>
<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
        echo $_POST["name"].",你好";
?>
练习:异步切换明星头像

XMLHttpRequest_API讲解

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

var xml=new XMLHttpRequest();
var xml=new ActiveXObject("Microsoft.XMLHTTP");
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请求注意点:

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 获得字符串形式的响应数据。
responseXML 获得 XML 形式的响应数据。
服务器

php如何读取文本数据

file_get_contents(文件路径);

Ajax数据传输XML

XML简介

<?xml version="1.0" encoding="UTF-8"?>
<singer>
<name>周杰伦</name>
<age>18</age>
<skill>途牛</skill>
</singer>

XML语法

<?xml version="1.0" encoding="UTF-8"?>
<!-- 下列标签都是被允许的 -->
<fox></fox>
<name></name>
<haha>标签内</haha>
<root>
  <name></name>
</root>
<!-- 使用属性配合标签表述信息 -->
<person sex="female">
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person>
<!-- 使用标签来表述信息 -->
<person>
  <sex>female</sex>
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person>

XML解析

<!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

header('content-type:text/xml;charset=utf-8');
<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
        header('content-type:text/xml;charset=utf-8');
        $text = file_get_contents("01-getFile-xml.xml");
        echo $text;
?>
<?xml version="1.0" encoding="UTF-8" ?>
<yijiang>
        <name>yijiang</name>
        <age>20</age>
        <sex>男</sex>
</yijiang>
Ajax中获取xml:
实际开发中xml用的频率不是很高,敲两遍就可以了。
案例:重写明星头像
<!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
    header('content-type:text/xml;charset=utf-8');
    echo file_get_contents('change-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语法

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

JSON解析

JSON图

JavaScript中
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);
<script type="text/javascript">
var jsonStr ={
  "name":"fox",
  "age":18,
  "skill":"撩妹"
};

var jsonObj = eval('('+jsonStr+')'); console.log(jsonObj);

</script>
PHP中
<?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的完整写法:
    <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
    echo file_get_contents("02-getFile-json.json");
?>
{
    "name":"jiang",
    "age":"16",
    "skill":"撩汉"
}

Ajax工具函数封装

原生Ajax写法

<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>
<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>

抽取公共部分

//优化,传入一个对象作为参数,对象中分别包含其它属性: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"。
<script src="jquery.min.js"></script>
<script>
        $.get("01-jq-get.php",{name:"yijiang",des:"大帅比"},function (data) {
            console.log(data);
        });
</script>
<?php
        echo $_GET['name']."是一个".$_GET['des'];
?>

$.post方法

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

$.getJSON方法

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

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

我们在向服务器提交数据时,如果使用的是Ajax需要手动将数据格式化,转化成类似name=fox&age=18这样的格式,jQuery已经帮助我封装好了一个格式化数据的方法。
<!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>

$.ajax({})方法

$.ajax()方法相比于前面的方法,拥有更为自由的定制性,可以替换$.get(),$.post()方法。
参数 描述
settings 可选。用于配置 Ajax 请求的键值对集合。可以通过 $.ajaxSetup() 设置任何选项的默认值。
$.ajax({
        url:'01.php',   //请求地址
        data:'name=fox&age=18',     //发送的数据
        type:'GET',     //请求的方式
        success:function (argument) {},     // 请求成功执行的方法
        beforeSend:function (argument) {},  // 在发送请求之前调用,可以做一些验证之类的处理
        error:function (argument) {console.log(argument);},   //请求失败调用
});
案例:注册界面

模板插件

模版引擎简介

var obj = {
     name:"fox",
     age:18,
     skill:"卖萌"
};
<ul>
  <li>姓名:fox</li>
  <li>年龄:18</li>
  <li>爱好:卖萌</li>
</ul>
<ul>
  <li>姓名:<%= name %></li>
  <li>年龄:<%= age %></li>
  <li>爱好:<%= skill %></li>
</ul>

模版插件原理

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

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基本使用

<script type="text/javascript" src = "./files/template-native.js"></script>
<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>
// 调用模板引擎的方法
var backHtml = template("templ01",data);
// 返回值就是填充好的内容
<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

<?php
    // echo "alert('天气不错哦')";
    $callBack = $_GET['callback'];
    $arr = array(
        'name' =>'大帅比' ,
        'color' =>'red'
    );
    echo $callBack."(".json_encode($arr).")";
?>
<!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>
jq已经帮我们封装好了jsonp的请求,直接使用即可:
<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()

<!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>

天气预报

瀑布流

什么是瀑布流?

瀑布流实现原理

// 为 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('我要玩游戏了哟');
    }
})
案例:(百度开发平台)
上一篇下一篇

猜你喜欢

热点阅读