AJAX

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.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的方法……

以上是关于AJAX的主要内容,如果未能解决你的问题,请参考以下文章

Javascript代码片段在drupal中不起作用

前端面试题之手写promise

Ajax 片段元标记 - Googlebot 未读取页面内容

执行AJAX返回HTML片段中的JavaScript脚本

javascript AJAX片段

Spring MVC 3.2 Thymeleaf Ajax 片段