首页 > 代码库 > AJAX(一)

AJAX(一)

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.1Host: localhostProxy-Connection: keep-aliveUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36Accept: */*Referer: http://localhost/php/09-21/01.htmlAccept-Encoding: gzip, deflate, sdch, brAccept-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.1Host: localhostContent-type: application/x-www-form-urlencodedProxy-Connection: keep-aliveUser-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2816.0 Safari/537.36Accept: */*Referer: http://localhost/php/09-21/01.htmlAccept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8Content-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 = "http://www.mamicode.com/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中的代码进行修改,修改后的代码如下:

<?phpheader("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的方法……

AJAX(一)