AJAX(一)
Ajax是Asynchronous Javascript和XML的简写,这一技术能够向服务器请求额外的数据而无需卸载页面,会带来更好的用户体验。
【前面的基础知识】
[关于同步和异步的了解]
同步:页面请求实时传给服务器,导致必填数据没有填的时候,要回到页面上重新从头填写,耗时长、客户体验差。
异步:在页面必填项写上必填选项,不用通过传给服务器判断必填内容是否已经填写完整,耗时短、用户体验强。
1、利用html+css来实现页面,表达信息;
2、用XMLHttpRequest和web服务器进行数据的异步交换
3、运营js操作DOM,实现动态局部刷新;
XMLHttpRequest对象的出现分割了同步和异步。XMLHttpRequest出现之前是同步的,出现之后是异步的。
[HTTP知识了解]
HTTP是计算机通过网络进行通信的规则
HTTP是一种无状态[不建立持久的连接]协议
一个完整的HTTP请求过程,通常有7个步骤:
1.建立TCP连接
2.web浏览器向web服务器发送请求命令
3.web浏览器发送请求头信息
4.web服务器应答
5.web服务器发送应答头信息
6.web服务器向浏览器发送数据
7.web服务器关闭TCP连接
一个HTTP请求一般由4部分构成:
1.HTTP请求的方法或动作[GET/POST]
GET:一般用于信息获取。使用URL传递参数。对所发送信息的数量也有限制[2000字符左右]。 幂等
POST:一般用于修改服务器上的资源。对所发送信息的数量无限制
2.正在请求的URL
3.请求头,包含一些客户端环境信息、身份验证信息等
4.请求体,即请求正文,包含客户提交的查询字符串信息、表单信息等
3和4之间一般会有一段空行 用来表示请求头的结束
一个HTTP响应一般由3部分构成:
1.一个数字和文字组成的状态码,用了显示请求是成功还是失败
2.响应头,和请求头一样包含许多有用的信息如服务器类型、日期事件、内容类型和长度等
3.响应体,即响应正文。
HTTP状态码由3为数字构成,其中首位数字定义了状态码的类型:
1xx:信息类,表示收到Web浏览器请求,正在进一步的处理中
2xx:成功,表示用户请求被正确接收,理解和处理 例如 200 ok
3xx:重定向,表示请求没有成功,客户必须采取进一步的动作
4xx:客户端错误,表示客户端提交的请求有错误, 如 404 NOT Found,意味着请求中所引用的文档不存在
5xx:服务器错误,表示服务器不能完成对请求的处理 如 500
更多关于HTTP的介绍请转至:http://www.cnblogs.com/foodoir/p/5905946.html
[XMLHttpRequest的用法]
1、XMLHttpRequest对象创建
var request; if(window.XMLHttpRequest){ request = new XMLHttpRequest(); //IE7+,Firefox,Chrome,Opera,Safari... }else{ request = new ActiveXObject("Microsoft.XMLHTTP"); //IE6,IE5 }else{ alert("No XHR object available."); }
或者:
function(){ if(tyof XMLHttpRequest != "undefined"){ return new XMLDocument(); }else if(typeof ActiveXObject != "undefined"){ if(typeof arguments.callee.activeXSting != "string"){ var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML.XMLHttp"],i,len; for(i=0,len=versions;i<len;i++){ try{ new ActiveXObj(versions[i]); arguments.callee.activeXString = versions[i]; break; }catch(ex){ //------ } } } return new ActiveXObject(arguments.callee.activeXString)); }esle{ throw new Error("No XHR object available."); } }
2、XMLHttpRequest发送请求
XMLHttpRequest发送请求有两个方法open和send
open(method,url,async),有三个参数:
method:规定HTTP发送请求的方式是get还是post,不区分大小写,一般来说用大写
url:请求地址(相对地址或绝对地址)
async:同步/异步(false/true),默认是异步也就是true,可以不用填写
send(string):发送到服务器(该参数可以填或者不填-----get方法不填或填null,post:一般要填)
get实例:
var request = new XMLHttpRequest(); request.open("GET","get.php",true); request.send();
post实例:
var request = new XMLHttpRequest(); requset.open("POST","post.php",true); request.send();
上面的这种做法是不正确的,POST请求的时候需要加上(一般不发送文件都用这个)request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");一定要写在open和send中间,具体做法如下:
var request = new XMLHttpRequest(); request.open(‘POST‘, ‘post.php‘, true) // 默认true异步操作 request.setRequestHeader(‘content-type‘, ‘application/x-www-form-urlencoded‘); //一般发送表单信息 需做该声明 request.send(‘name=foodoir&sex=男‘);
[XMLHttpRequest取得响应]
在接收到响应后,响应的数据会自动填充XHR对象的属性,相关的属性简介如下:
responseTest:作为响应主体被返回的文本
responseXML:如果响应的内容是“text/xml”或“application/xml”,这个属性将保存包含着响应数据的XML DOM文档
status:响应的HTTP状态
statusText:HTTP状态的说明
下面我们直接看一个例子:
//先new一个xmlHttpRequest对象,再调用open方法,再发送一些数据,最后对这个响应进行监听。 var request = new XMLHttpRequest(); request.open("GET","get.php",true); request.send(); // 为request注册监听事件 request.onreadystatechange = function(){ if(request.readyState === 4 && request.status === 200){ // 当请求成功时,执行... ... } }
或者说我们还可以这样做:
var xhr = CreateXHR(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4){//检测XHR的readyState属性 if((xhr.status >= 200 && xhr.status <= 300) || xhr.status == 304){ alert(xhr.responseText); }else{ alert("Request was unsuccessful:" + xhr.status); } } }; xhr.open("GET","get.php",true); xhr.send(null);
补充:关于readyState属性值
0:尚未初始化。open()方法还没有调用
1:启动。open()方法已经调用,send()方法还没有调用
2:发送。open()方法已经调用,s还没有接收到响应
3:接收。已经接收到部分响应数据
4:完成。已经接收全部的相应数据,而且已经可以在客户端使用了
[PHP的一些知识]
关于PHP的作用:PHP是一种创建动态交互性站点的服务器端脚本语言; PHP能够生成动态页面内容; PHP能够创建、打开、读取、写入、删除以及关闭服务器上的文件; PHP能够接受表单数据; PHP能够发送并取回cookies; PHP能够添加、删除、修改数据库中的数据; PHP能够限制用户访问网站中的某些页面
为了运行PHP,我们需要搭建一个运行环境,在这里推荐以一个软件xampp(已经将我们需要的环境配置好了),其下载地址:https://www.apachefriends.org/download.html
PHP 服务器端实现:PHP脚本以<?php 开头 以?>结尾;PHP文件的默认文件扩展名是 .php;PHP语句以分号结尾(;)
下面我们来看一段PHP代码:
<?php //echo "hello world"; //这是一个纯PHP的文件, //设置页面内容是html编码格式是utf-8,这样防止页面返回的值是乱码 //text/plain; application/json;text/xml;text/html;application/javascript;这都是高度客户端 //服务器响应过来的内容它的格式是什么。text/plain;是代表格式是纯文本,application/json;是代表格式是json字符串 header("Content-Type:text/plain;charst = utf-8"); //header("Content-Type:application/json;charst = utf-8"); //header("Content-Type:text/xml;charst = utf-8"); //header("Content-Type:text/html;charst = utf-8"); //header("Content-Type:application/html;charst = 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(); }else if($_SERVER["REQUEST_METHOD"] == "POST"){ create(); } //通过员工编号搜索员工 function search(){ //在PHP中,超全局变量,也就是我们理解的全局变量,它可以在一个脚本的全部作用域中都可以用, //检查是否有员工编号的参数 //isset检测变量是否设置;empty判断值为否为空 //超全局变量 $_GET 和 $_POST 用于收集表单数据 //首先我们检查一下参数里边有没有员工的编号,如果没有员工的编号,我们是没法搜索员工的,所以我们用这种方式来 //检查一下我们的GET的url参数中有没有number这么一个字段,isset是检查变量是否设置,也就是这个number变量有没有 //empty代表这个变量是否为空,在这里,如果这个变量没有或者为空,我们都显示参数错误:echo "参数错误"; //也就是说页面直接返回“参数错误”,在浏览器中预览一下,我们没有任何参数的情况下,代表的是一个get请求,当我们没有 //加number参数的时候。它会直接返回参数错误,当然如果有参数错误,就直接查询了。查询,就把这个number参数获取到 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"]."信息保存成功!"; } ?>
PHP服务端的代码已经写完了,但是这个代码写的对不对呢,能不能顺利的执行呢,我们需要进行一下测试 这个所谓的测试可不是我们把客户端Ajax请求各个事件都给写完之后,来对它进行测试,我们需要在没有客户端的情况下,就对服务端的一些请求进行一些测试,这是怎么样来做到的呢?我们通过一个工具fiddler工具(Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件,这些都可以让你胡乱修改的意思)。 Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还提供了一个用户友好的格式。),这个工具可以监听整个电脑所有发出的HTTP请求,可以监听它们传入的值,和相应回来的值,当然在这里边它还可以去模拟
在百度上搜索fiddler就可以下载到,直接安装。不想下载fiddler,可以下载chrome插件postman同样的功能。
fiddler可以监听电脑上所有的HTTP请求(GET和POST等)监听他们传入的值和返回的值。后台测试接口工具。
使用:右边栏有compose都标签页。输入刚才地址后excuse他。双击左栏的记录。用post请求的时候要用到contentType:application/x-www-form-urlencodeed,告诉服务器是一个post请求,并且是写在url里面。
下面我们在Fiddler软件中输入:
GET http://localhost/php/09-21/01.php HTTP/1.1 Host: localhost Proxy-Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36 Accept: */* Referer: http://localhost/php/09-21/01.html Accept-Encoding: gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8
显示的结果为:参数错误,如图:
原因分析:我们没有输入输入参数
测试1:我们在后面传入参数,number。代码:GET http://localhost/php/09-21/01.php?number HTTP/1.1
结果1:参数错误
测试2:我们在后面传入参数,number=1。代码:GET http://localhost/php/09-21/01.php?number=1 HTTP/1.1
结果2:没有没有找到员工。
测试3:我们在后面传入参数,number=101.代码:GET http://localhost/php/09-21/01.php?number=101 HTTP/1.1
结果3:找到员工:员工编号:101,员工姓名:洪七,员工性别:男,员工职位:总经理
下面我们用POST方法,输入如下代码:
POST http://localhost/php/09-21/01.php?number=101 HTTP/1.1 Host: localhost Content-type: application/x-www-form-urlencoded Proxy-Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36 Accept: */* Referer: http://localhost/php/09-21/01.html Accept-Encoding: gzip, deflate, sdch, br Accept-Language: zh-CN,zh;q=0.8 Content-Length: 54
结果显示为:参数错误,员工信息填写不全,如图:
原因分析:还是没有输入参数
测试1:我们在后面传入参数,代码:name=foodoir&number=104&sex=男&job=web前端工程师
结果1:员工foodoir信息保存成功!效果如图:
大家在日常进行web开发的时候,有时候后台做好之后,总是等待依赖前台做好之后,可以去调试,其实完全没有必要我们只需要约定好接口, 发送的报文和返回的报文,通过fiddler或者类似的工具,直接就可以进行调试了。不需要依赖前台是否完成,在这里推荐一个网站(http://www.imooc.com/learn/37)有专门讲解fiddler的使用方法。
【AJAX实战】
我们先完成html代码
<h1>员工查询</h1> <lable>请输入员工编号:</lable> <input type="text" id="keyword"/> <button id="search">查询</button> <p id="searchResult"></p> <hr /> <h1>员工创建</h1> <lable>请输入员工姓名:</lable> <input type="text" id="staffName"/><br /> <lable>请输入员工编号:</lable> <input type="text" id="staffNumber"/><br /> <lable>请输入员工性别:</lable> <select id="staffSex" name="sex"> <option>男</option> <option>女</option> </select><br /> <lable>请输入员工职位:</lable> <input type="text" id="staffJob"/><br /> <button id="save">保存</button> <p id="createResult"></p> <hr />
进一步完成Javascript代码
document.getElementById(‘search‘).onclick = function(){ //发送ajax请求并处理 var request = new XMLHttpRequest(); //request.open("GET","01.php") request.open("GET","01.php?number="+document.getElementById("keyword").value); request.send(); request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status === 200){ document.getElementById("searchResult").innerHTML = request.responseText; }else{ alert("发生错误:"+request.status); } } }; }; document.getElementById(‘save‘).onclick = function(){ var request = new XMLHttpRequest(); request.open("POST","01.php"); var data = "name=" + document.getElementById("staffName").value + "&number=" + document.getElementById("staffNumber").value + "&sex=" + document.getElementById("staffSex").value + "&job=" + document.getElementById("staffJob").value; request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//在send方法中这段代码是很重要的 request.send(data); request.onreadystatechange = function(){ if(request.readyState === 4){ if(request.status === 200){ document.getElementById("createResult").innerHTML = request.responseText; }else{ alert("发生错误"+request.status); } } }; };
对我们的代码进行测试,如图:
从结果中我们可以看出,员工的查询和新建员工的保存是互不影响的,并且每一步点击都会执行相应的操作。
然后我们发现用responseTest,纯文本的方式不太好,我们可不可以用JSON的格式来传递信息(关于更多JSON的知识,请移步至:http://www.cnblogs.com/foodoir/p/5894760.html)
这样,我们就需要对PHP中的代码进行修改,修改后的代码如下:
<?php 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"=>"产品经理"), ); if($_SERVER["REQUEST_METHOD"] == "GET"){ search(); }else if($_SERVER["REQUEST_METHOD"] == "POST"){ create(); } function search(){ if(!isset($_GET["number"]) || empty($_GET["number"])){ echo ‘{"success":false,"msg":"参数错误"}‘; return; } global $staff; $number = $_GET["number"]; $result = ‘{"success":false,"msg":"没有找到员工"}‘; 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; } echo ‘{"success":true,"msg":"员工:‘.$_POST["name"].‘信息保存成功!"}‘; } ?>
这里我们用到了HTTP的相关知识,JSON的相关知识等,有了这些基础我们学习起AJAX还是比较简单的。后面还打算学习AJXA跨域的相关知识,jquery中使用AJXA的方法……