代码改变世界

Ajax相关概念和简单例子的应用

2017-03-17 13:52  SiestaKc  阅读(247)  评论(0编辑  收藏  举报

一直把Ajax和HTTP协议看作是难懂的驾驭不住的两块知识,所以总寸侥幸心理地跳过和忽略这两块的知识,但是最近看了春招的很多招聘信息,这两项都是作为技能要求之一的,特别是HTTP协议,趁着学习劲头还足,找了视频来看,倒也没觉得有特别的难了,应该是入门级的原因,深入起来估计也是一大块要用脑的地方,且学且努力~这一篇主要还是对慕课网上的【Ajax全接触】一课知识点的梳理和总结。

一、Ajax相关概念

1.同步和异步

同步:用户填写信息完成之后,全部提交给服务器,等待服务器的回应,一次性全部的。

异步:当用户填写完一条信息之后,这条信息会自动向服务器提交,然后服务器响应回客户端,在此同时,客户继续填写表格的信息,即向服务器请求多次,既节省了客户的时间,又提高了用户的体验。

XMLHttpRequest对象来实现这一功能,也需要javascript来操作DOM实现局部的信息更新。

Ajax(Asynchronous Javascript And XML)

1、运用HTML与CSS实现页面,表达信息;

2、运用XMLHttpRequest和web服务器进行数据的异步交换

3、运用Javascript操作DOM,实现动态局部更新。

2.XMLHttpRequest对象创建

创建一个XHR对象

var request = new XMLHttpRequest();

3.HTTP请求

3-1,一个完整HTTP请求过程,包含7个步骤:

a.建立CTP连接

b.web浏览器向web服务器发送请求命令

c.web浏览器发送请求头信息

d.web服务器应答

e.web服务器向浏览器返回数据

f.web服务器关闭TCP连接

3-2,一个HTTP请求包括4部分

a.HTTP请求的方法和动作,比如GET和POST请求

     GET:一般用于信息的获取(使用URL传递参数,不过对发送信息的数量有限制,一般在2000个字符)

     POST:一般用于修改服务器上的资源(从表单中发送信息,这信息在表单栏中是不可见的,一般是嵌入到请求体中,对发送信息的数量无限制)

b.正在请求的URL,知道请求的地址是什么

c.请求头(包含一些客户端环境信息,身份验证信息等)


该空行表示:请求头已经结束,接下来是请求体正文


 d.请求体,也就是请求正文,请求正文中可以包括客户提交的查询字符串信息,表单信息等

3-3,一个HTTP响应包括4部分

      a.一个数字或文字组成的状态码,用来显示成功还是失败

      b.响应头,响应头也和请求头一样包含许多有用的信息,但是是服务器类型、日期时间、内容类型和长度等。

      c.响应体,也就是响应正文。

3-4,HTTP状态码,由3个数字构成,首位数字定义了状态的类型

      1XX:信息类,表示收到web浏览器的请求,正在进一步的处理

      2XX:成功,表示用户请求被接收,理解和处理。200OK

      3XX:重定向,表示请求没有成功,客户必须采取进一步的动作

      4XX:客户端错误,表示客户端提交的请求有错误,例如400 NOT FONUD:意味着请求中所引用的文档不存在

      5XX:服务器错误,表示服务器不能完成对请求的处理。     

4.XMLHttpRequest发送请求

4-1,open("<method>","<url>",<isAsync>?):规定请求的类型、url和是否异步等。

     <method>:指定请求的类型(GET\POST);

     <url>:指定服务器上将要访问的文件(文件在服务器上的位置);

     <isAsync>:指定请求是否以异步方式发送和处理,默认为true(异步,需要编写onreadstateychange函数)

4-2,setRequestHeader("<header>","<value>"):向请求添加HTTP头。

    <header>:头的名称

     <value>:头的值

4-3,send(<text>?):将请求发送到服务器

    <text>:参数;

    POST请求必须填写<text>

    GET可省略不填,或者写null.

5.XMLHttpRequest取得响应

5-1.XMLHttpRequest取得响应

    a.responseText:获得字符串形式的响应数据

    b.responseXML:获得XML形式的响应数据

    c.status和statusText:以数字和文本形式返回HTTP状态码

    d.getAllResponseHeader():获取所有的响应报头

    e.getResponseHeader():查询响应中的某个字段的值

5-2.onreadystatechange函数中readyState属性

    0:请求未初始化,open还没有调用

    1:服务器连接已建立,open已经调用了

    2:请求已经接受,也就是收到了头信息了

    3:请求处理中,也就是收到了响应主体了

    4:请求已完成,且响应已就绪,响应已经完成

 

二、Ajax实现例子(PHP+Ajax)

1.XAMPP :把Apache网页服务器与PHP、Perl及MariaDB集合在一起的安装包,运行用户可以在自己的电脑上轻易地建立网页服务器。

       使用sublime编辑器怎样使用XAMPP??

     1、先开启xampp运行Apache。注意:xampp安装不要改配置文件地址!!!改了就出错了!!!

     2、找到配置文件,并在xampp/htdocs下面新建一个文件夹作为你的根目录,譬如:ajax

     3、在根目录随便创建一个HTML文件,输入文字以备测试,譬如:practise.html

   4、打开chrome浏览器,输入:localhost/根目录/HTML文件名,如果可以出现就说明运行本地服务器成功,譬如:localhost/ajax/practise.html

2.服务器端的额实现:staff.php

<?php
//设置页面内容是html编码格式是UFT-8
header("Content-Type:text/plain;charset=utf-8");

//定义一个多维数组,包含员工的信息,每条员工信息为一个数组
$staff = array
(
    array("name"=>"张三","number"=>"101","sex"=>"男","job"=>"总经理"),
    array("name"=>"李四","number"=>"102","sex"=>"女","job"=>"产品经理"),
    array("name"=>"黄五","number"=>"103","sex"=>"女","job"=>"开发工程师")
);

//判断如果是get请求,则进行搜索;如果是post请求,则进行新建
//$_SERVER是一个超全局变量,在一个脚本的全部作用域中都可用,不使用global关键字
//$_SERVER["REQUEST_METHOD"]返回页面使用的请求方法
if($_SERVER["REQUEST_METHOD"]=="GET"){
    search();
}elseif($_SERVER["REQUEST_METHOD"]=="POST"){
     create();
}

//通过员工标号搜索员工
function search(){
    //检查是否有员工编号的参数
    //isset检测变量是否设置;empty判断值是否为空
    //超全局变量$_GET和$_POST用于收集表单数据
    if(!isset($_GET["number"]) || empty($_GET["number"])){
        echo  "参数错误";
        return;
    }
    //函数之外声明的变量拥有global作用域,只能在函数以外进行访问。
    //global关键词用于访问函数内部的全局变量
    global $staff;
    //获取number参数
    $number = $_GET["number"];
    $result = "没有找到员工。";
    
    //遍历$staff多维数组,查找key值为number的员工是否存在,如果存在,则修改返回结果
    foreach($staff as $value){
        if($value["number"] == $number){
            $result = "找到员工:员工编号:".$value["number"].",员工姓名:".$value["name"].
            ",员工性别:".$value["sex"].",员工职位:".$value["job"];
            break;
        }
    }
    echo $result;
}

//创建员工
function create(){
    //判断信息是否填写完全
    if(!isset($_POST["name"])||empty($_POST["name"])
      ||!isset($_POST["number"])||empty($_POST["number"])
      ||!isset($_POST["sex"])||empty($_POST["sex"])
      ||!isset($_POST["job"])||empty($_POST["job"])){
          echo "参数错误,员工信息填写不全";
          return;
      }
    //TODO:获取POST表单数据并保存到数据库
    
    //提示保存成功
    echo"员工:".$_POST["name"]."信息保存成功!";
    }
?>

接下来就是测试服务器端的代码了,可使用Fiddler工具

fiddler工具,可看网站中的“ Fiddler工具使用" (http://www.imooc.com/learn/37)课程,后台测试接口工具
Content-Type:application/x-www-form-urlencoded
的正确设置。。
fiddler可用于调试服务器代码(无需客户端代码)。
Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件,这些都可以让你胡乱修改的意思)。 Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还提供了一个用户友好的格式。
fiddler可以监听电脑上所有的HTTP请求(GET和POST等)监听他们传入的值和返回的值。后台测试接口工具。
使用:右边栏有compose都标签页。输入刚才地址后excuse他。双击左栏的记录。用post请求的时候要用到contentType:application/x-www-form-urlencodeed,告诉服务器是一个post请求,并且是写在url里面。
在右下栏的requestbody写上请求正文。
Content-Type:application/x-www-form-urlencoded

3.客户端的实现demo.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<style>
body,input,button,select,h1{
    font-size:16px;
    line-height:1.8;
}
</style>
</head>

<body>
<h1>员工查询</h1>
<label>请输入员工编号:</label>
<input type="text" id="keyword"/>
<button id="search">查询</button>
<p id="searchResult"></p>

<h1>员工创建</h1>
<label>请输入员工姓名:</label>
<input type="text" id="staffName"/><br/>
<label>请输入员工编号:</label>
<input type="text" id="staffNumber"/><br/>
<label>请选择员工性别:</label>
<select id="staffSex">
<option></option>
<option></option>
</select><br/>
<label>请输入员工职位</label>
<input type="text" id="staffJob"><br/>
<button id="save">保存</button>
<p id="createResult"></p>


<script>
//怎么通过查询按钮取得后台服务器上的值
//通过AJAX实现了局部更新查询模块,返回查询结果,而不更新整个页面
document.getElementById("search").onclick = function(){
     //发送Ajax查询请求并处理
     //1.new 一个XHR对象
     var request = new XMLHttpRequest();
     //2.调用open方法,它是一个get请求,直接调用staff.php的地址和该参数是员工编号的参数number
     request.open("GET","staff.php?number="+document.getElementById("keyword").value);
     //3.请求已经发送
     request.send();
     //4.更新页面中查询到的结果
     request.onreadystatechange = function(){
         if(request.readyState === 4){
             if(request.status === 200){
                //请求成功,更新查询结果,
                //将服务器端响应的报文赋予该查询结果
                document.getElementById("searchResult").innerHTML = request.responseText;
      }else {
            alert("发生错误!"+ request.status);
          }
     }
    }    
}

//同样的方法通过Ajax局部更新员工创建模块
//更新数据,使用POST方式
document.getElementById("save").onclick = function(){
     
     var request = new XMLHttpRequest();
     request.open("POST","staff.php");
     //GET方式直接将参数传给url,而POST方式则是将参数传给send,
     //所以,先构造参数data,
     //将创建模块中文本框的值拼成参数,在每个值中需要&符号将参数隔开
     var data = "name=" +document.getElementById("staffName").value
               +"&number=" +document.getElementById("staffNumber").value
               +"&sex="+document.getElementById("staffSex").value
               +"&job="+document.getElementById("staffJob").value;
    //当POST方式时,一定要在open和send方法中间添加setRequestHeader()方法
     request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
     request.send(data);
     
     request.onreadystatechange = function(){
         if(request.readyState === 4){
             if(request.status === 200){
//请求成功,将保存结果返回,局部更新页面信息 document.getElementById(
"createResult").innerHTML = request.responseText; }else{ alert("发生错误:"+request.status); } } } } </script> </body> </html>

然后,开始测试页面,

输入员工编号:1时,查询结果

能够看到HTTP请求部分的请求方法、URL、请求头和查询字符串等信息。


同样的,也能看到HTTP响应头信息,和响应主体。
当输入101时,查询到该员工的信息,


然后将响应主体信息ResponseText更新到网页的局部,实现代码为修改demo.html的onreadystatechange函数
  request.onreadystatechange = function(){
         if(request.readyState === 4){
             if(request.status === 200){
                //请求成功,更新查询结果,
                //将服务器端响应的报文赋予该查询结果
                document.getElementById("searchResult").innerHTML = request.responseText;
      }else {
            alert("发生错误!"+ request.status);
          }
     }
    }    



request.open("POST","staff.php");

三、JSON

1.JSON:JavaScript对象表示法(JavaScript Object Notation)

JSON:是存储和交换文本信息的语法,类似XML。它采用键值对的方式来组织易于人们理解,也易于机器解析的和生成的计算机语言

JSON:是独立于语言的,不管什么语言都可以解析json,只需要按照json的规则来

2.在JS中解析json的方法:

 1、eval(jsondata),不仅解析了json的字符串,还解析了js的方法,这种方法很是危险

 2、JSON.parse(jsondata)这种方法最安全,并且可以解析出json错误来

可以运用JSONLint检验工具来校检JSON语句

3.用json方式改写php代码,需要规定统一的格式,所有从服务器返回的额json字符串应该是这样的

需要改变php中header的信息

header("Content-Type:application/json;charset=utf-8");

并且所有的echo值都要做此改变

{

  "success":true,//作为请求是否成功的标记

 "msg":"xxx"//请求返回的值

}

<?php
//设置页面内容是html编码格式是UFT-8
//header("Content-Type:text/plain;charset=utf-8");
header("Content-Type:application/json;charset=utf-8");
//定义一个多维数组,包含员工的信息,每条员工信息为一个数组
$staff = array
(
    array("name"=>"张三","number"=>"101","sex"=>"男","job"=>"总经理"),
    array("name"=>"李四","number"=>"102","sex"=>"女","job"=>"产品经理"),
    array("name"=>"黄五","number"=>"103","sex"=>"女","job"=>"开发工程师")
);

//判断如果是get请求,则进行搜索;如果是post请求,则进行新建
//$_SERVER是一个超全局变量,在一个脚本的全部作用域中都可用,不使用global关键字
//$_SERVER["REQUEST_METHOD"]返回页面使用的请求方法
if($_SERVER["REQUEST_METHOD"]=="GET"){
    search();
}elseif($_SERVER["REQUEST_METHOD"]=="POST"){
     create();
}

//通过员工标号搜索员工
function search(){
    //检查是否有员工编号的参数
    //isset检测变量是否设置;empty判断值是否为空
    //超全局变量$_GET和$_POST用于收集表单数据
    if(!isset($_GET["number"]) || empty($_GET["number"])){
        echo '{"success":false,"msg":"参数错误"}';
        return;
    }
    //函数之外声明的变量拥有global作用域,只能在函数以外进行访问。
    //global关键词用于访问函数内部的全局变量
    global $staff;
    //获取number参数
    $number = $_GET["number"];
    $result = '{"success":false,"msg":"没有找到员工"}';
    
    //遍历$staff多维数组,查找key值为number的员工是否存在,如果存在,则修改返回结果
    foreach($staff as $value){
        if($value["number"] == $number){
            $result = '{"success":true,"msg":"找到员工:员工编号:'.$value["number"].',员工姓名:'.$value["name"].
            ',员工性别:'.$value["sex"].',员工职位:'.$value["job"].'"}';
            break;
        }
    }
    echo $result;
}

//创建员工
function create(){
    //判断信息是否填写完全
    if(!isset($_POST["name"])||empty($_POST["name"])
      ||!isset($_POST["number"])||empty($_POST["number"])
      ||!isset($_POST["sex"])||empty($_POST["sex"])
      ||!isset($_POST["job"])||empty($_POST["job"])){
          echo '{"success":false,"msg":"参数错误员工信息填写不全"}';
          return;
      }
    //TODO:获取POST表单数据并保存到数据库
    
    //提示保存成功
    echo '{"success":true,"msg":"员工:'.$_POST["name"].'信息保存成功!"}';
    }
?>

在demo.html页面上则需要解析json语句,并且返回data.msg

 request.onreadystatechange = function(){
         if(request.readyState === 4){
             if(request.status === 200){
                 //解析json语句并判断
                 var data = JSON.parse(request.responseText);
                 if(data.success){
                //请求成功,更新查询结果,
                //将服务器端响应的报文赋予该查询结果
                document.getElementById("searchResult").innerHTML = data.msg;
                 }else{
                document.getElementById("searchResult").innerHTML = "出现错误:" +data.msg;
                 }}else{
                 alert("发生错误:"+request.status);
             }
     }

 

四、运用jQuery实现Ajax

jQuery.ajax([settings])

type:类型,”POST“或”GET“,默认为”GET“

url:发送请求的地址

data:是一个对象,连同请求发送到服务器的数据

dataType:与其服务器返回的数据类型,如果不指定,jQuery将自动根据HTTP包的MIME信息来智能判断,一般我们采用json格式,可以设置为”json“

success:是一个方法,请求成功后的回调函数。传入返回后的数据,以及包含成功代码的字符串

error:是一个方法,请求失败时调用此函数。传入XMLHttpRequest对象

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>使用jQuery中的Ajax</title>
<style>
body,input,button,select,h1{
    font-size:16px;
    line-height:1.8;
}
</style>
</head>

<body>
<h1>员工查询</h1>
<label>请输入员工编号:</label>
<input type="text" id="keyword"/>
<button id="search">查询</button>
<p id="searchResult"></p>

<h1>员工创建</h1>
<label>请输入员工姓名:</label>
<input type="text" id="staffName"/><br/>
<label>请输入员工编号:</label>
<input type="text" id="staffNumber"/><br/>
<label>请选择员工性别:</label>
<select id="staffSex">
<option></option>
<option></option>
</select><br/>
<label>请输入员工职位</label>
<input type="text" id="staffJob"><br/>
<button id="save">保存</button>
<p id="createResult"></p>

<script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.js"></script>
<script>
    $(document).ready(function(){
        //改造好的查询模块的jQuery的Ajax
        $("#search").click(function(){
            $.ajax({
                type : "GET",
                url : "staff2.php?number="+$("#keyword").val(),
                dataType : "json",
                success:function(data){
                    if(data.success){
                        $("#searchResult").html(data.msg);
                        }else{
                        $("#searchResult").html("出现错误:"+data.msg);        
                     }
                    },
                error:function(jqXHR){
                        alert("发生错误:"+jqXHR.status);
                    }
                
                });
            });
            
        //改造好的保存模块的jQuery的Ajax
        $("#save").click(function(){
            $.ajax({
               type : "POST",
               url : "staff2.php",
               dataType : "json",
               data : {
                   name : $("#staffName").val(),
                   number : $("#staffNumber").val(),
                   sex : $("#staffSex").val(),
                   job : $("#staffJob").val(),
                   },
               success:function(data){
                  if(data.success){
                      $("#createResult").html(data.msg);
                   }else{
                       $("#createResult").html("出现错误:"+data.msg);
                      }
                },
               error:function(jqXHR){
                       alert("发生错误:"+jqXHR.status);
            }           
            });
        });
            
});
</script>

</body>
</html>