学习要点
- JavaScript实现Ajax
- jQuery实现Ajax
- JSON
- PHP的JSON函数
- JavaScript处理JSON数据
JavaScript实现Ajax
什么是Ajax
- 搜狗地图
- 百度搜索自动补全
- 百度登陆验证
- 百度用户注册验证
使用Ajax的好处
- Ajax的特点:无刷新——不刷新整个页面,只刷新局部。
- 无刷新的好处
- 只更新部分页面,有效利用带宽
- 提供连续的用户体验
- 提供类似C/S的交互效果,操作更方面
传统Web与Ajax的差异
Ajax简介
- Ajax:异步刷新技术
- Ajax工作流程
备注:XML/JSON/HTML是用来封装请求或响应数据的众多数据格式中的一部分。还有如Script、JSONP、text等其他的数据格式。
XMLHttpRequest
- XMLHttpRequest是整个Ajax技术的核心,提供异步发送请求的能力。
- 创建XMLHttpRequest对象
IE5和IE6
xmlHttpRequest=new ActiveXObject("Microsoft.XMLHTTP");
其他浏览器
xmlHttpRequest=new XMLHttpRequest();
- XMLHttpRequest常用属性
1.readystate: XMLHttpRequest的状态信息(就绪状态)
2.onreadystatechange:指定回调函数
3.status:HTTP的状态码
注意:就绪状态是4且状态码是200,方可处理服务器数据
4.statusText :返回当前请求的响应状态
5.responseText:获得响应的文本内容
6.responseXML:获得响应的XML文档对象
- XMLHttpRequest常用方法
方 法 |
说 明 |
open( String method[, String url[, Boolean async[, String user[, String password]]]]) |
用于创建一个新的HTTP请求。 Method:设置请求方法,POST或者GET,对大小写不敏感。 Url:服务器地址 Async:指定请求是否是异步方式,默认true。 User:服务器需要验证,则需要填写用户名。 Password:密码。如果用户名为空,则此值被忽略。 |
send(String data) |
发送请求到服务器端。 Data:字符串类型。此参数值取决于open方法中的method参数,如果method为POST,则该参数需要指定;如果method为GET,则该参数为null。 |
abort() |
取消当前请求。 |
setRequestHeader( String header, String value) |
设置请求的HTTP头信息。 Header:要指定的HTTP头信息。 Value:HTTP头名称对应的值。 |
getResponseHeader( String header) |
从响应中获取指定的HTTP头信息。 Header:要获取的指定HTTP头。 |
getAllResponseHeaders() |
获取响应的所有HTTP头信息 |
实现Ajax的过程分为发送请求和处理响应两个步骤:
- 发送请求分为GET和POST方法。
- 响应有responseText和responseXML两种方式。
本次介绍处理responseText。
JavaScript实现Ajax
- 使用Ajax发送GET请求及处理响应
客户端主要脚本:
<script src="js/jquery-1.11.3.js" type="text/javascript"></script> <script type="text/javascript"> function validate() { var uname = $("#uname").val(); if (uname == null || uname == "") { $("#msg").html("用户名不能为空!"); } else { //1.创建XMLHttpRequest对象 xmlHttpRequest = createXmlHttpRequest(); //2.设置回调函数 xmlHttpRequest.onreadystatechange = callBack; //3.初始化XMLHttpRequest组件 var url = "D01Server.php?uname=" + uname; xmlHttpRequest.open("get", url, true);//get方式 //4.发送请求 xmlHttpRequest.send(null); } }; //创建XmlHttpRequest对象 function createXmlHttpRequest() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else {//返回值为false时说明是老版本IE浏览器(IE5和IE6) return new ActiveXObject("Microsoft.XMLHTTP"); } }; //Ajax 回调函数 function callBack() { //读取响应结束,并且正确返回 if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) { var data = xmlHttpRequest.responseText; $("#msg").html(data); } } </script> … … <body> <form action=""> <p> 用户名:<input type="text" name="uname" id="uname" onblur="validate();"> <span id="msg" style="color:red;"></span> </p> </form> </body>
服务器端主要脚本:
<meta charset="UTF-8"> <?php $name=$_GET['uname']; if("admin"==$name){ echo "用户名被占用!"; }else { echo "用户名可以使用"; } ?>
- 使用Ajax发送POST请求及处理响应
客户端主要脚本:
<script src="js/jquery-1.11.3.js" type="text/javascript"></script> <script type="text/javascript"> function validate() { var uname = $("#uname").val(); if (uname == null || uname == "") { $("#msg").html("用户名不能为空!"); } else { //1.创建XMLHttpRequest对象 xmlHttpRequest = createXmlHttpRequest(); //2.设置回调函数 xmlHttpRequest.onreadystatechange = callBack; //3.初始化XMLHttpRequest组件 var url = "D02Server.php"; xmlHttpRequest.open("post", url, true);//post方式 xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //4.发送请求 var data = "uname=" + uname;//需要发送的数据信息,name为用户名输入框获取的值 //var data = {"uname":uname}; xmlHttpRequest.send(data); } }; //创建XmlHttpRequest对象 function createXmlHttpRequest() { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else {//返回值为false时说明是老版本IE浏览器(IE5和IE6) return new ActiveXObject("Microsoft.XMLHTTP"); } }; //Ajax 回调函数 function callBack() { if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == 200) { var data = xmlHttpRequest.responseText; if ($.trim(data) == "true") { $("#msg").html("用户名已被使用!"); } else { $("#msg").html("用户名可以使用!"); } } } </script>
服务器端主要脚本:
<?php $name=$_POST['uname']; if("admin"==$name){ echo "true"; }else { echo "false"; } ?>
上机练习1:实现无刷新邮箱验证
需求说明:实现无刷新验证注册邮箱
在用户注册页面,当E-mail文本框失去焦点时,判断用户是否存在。
jQuery实现Ajax
使用javascript实现ajax有很多缺点…方法、属性、常用值较多不好记忆,步骤繁琐,浏览器兼容问题。
jQuery提供了一些常用的ajax方法:$.ajax()、$.get() 、$.post()、$.getJSON()、load()。相比js实现,更加简洁和方便。
$.ajax()方法
- 作用:通过 HTTP 请求加载远程数据。jQuery中实现ajax最底层方法,参数多,灵活性高。
- 语法格式:
$.ajax( [ settings ] );
- 常用属性参数:
属性名 |
说 明 |
String url |
发送请求的地址,默认为当前页地址 |
async |
默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。 注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。如果需要在回调函数中确保完成执行相关指令,把该值设置未false。 |
String type |
请求方式(POST或GET,默认为GET) |
Number timeout |
设置请求超时时间 |
Object data 或 String data |
发送到服务器的数据 |
String dataType |
预期服务器返回的数据类型,包括:XML、HTML、Script、JSON、JSONP、text |
boolean global |
表示是否触发全局Ajax事件,默认为true |
- 常用函数参数
函 数 |
说 明 |
function beforeSend( XMLHttpRequest xhr) |
发送请求前调用的函数 参数xhr:可选 |
function complete( XMLHttpRequest xhr, String ts) |
请求完成后调用的函数 参数xhr:可选 参数ts:可选,描述请求类型的字符串 |
function success( Object result,String ts) |
请求成功后调用的函数 参数result:可选,由服务器返回的数据 参数ts:可选,描述请求类型的字符串 |
function error( XMLHttpRequest xhr, String em,Exception e) |
请求失败时被调用的函数 参数xhr:可选 参数em:可选,错误信息 参数e:可选,捕获的异常对象 |
- $.ajax()实现Ajax示例代码
<script src="js/jquery-1.11.3.js" type="text/javascript"></script> <script type="text/javascript"> function validate() { var uname = $("#uname").val(); if (uname == null || uname == "") { $("#msg").html("用户名不能为空!"); } else { $.ajax({ url : "D03Server.php", type : "get", data:{"uname":uname}, dataType : "text", success : function(result) { if ($.trim(result) == "true") { $("#msg").html("用户名已被使用!"); } else { $("#msg").html("用户名可以使用!"); } }, error : function() { alert("用户名验证拾出现错误,请联系管理员!"); } }); } }; </script>
上机练习2:使用$.ajax()方法实现异步检查注册邮箱是否已经存在。
需求说明:使用$.ajax()方法重新实现上机练习1。
注:使用jQuery提供的$.trim(String str)方法可以将传入的字符串前后空格去除。
$.get()
- 语法格式:
$.get(url ,data,success(resp,status,xhr), dataType);
- 常用参数
参数名 |
说 明 |
String url |
规定将请求发送到目标URL |
Object data 或 String data |
可选。规定连同请求发送到服务器的数据 |
function success( Object result, String status, XMLHttpRequest xhr) |
可选。请求成功后调用的函数 参数result:可选。服务器返回的结果数据 参数status:可选。请求的状态 参数xhr:可选 |
String dataType |
可选。预期服务器返回的数据类型,包括:XML、HTML、Script、JSON、JSONP、text |
- 示例代码
<script src="js/jquery-1.11.3.js" type="text/javascript"></script> <script type="text/javascript"> function validate(){ var uname = $("#uname").val(); if(uname==null || uname==""){ $("#unameDiv").html("用户名不能为空!"); }else{ $.get('D04Server.php','uname='+uname,function(result){ if($.trim(result) == "true"){ $("#unameDiv").html("用户名已被使用!"); }else{ $("#unameDiv").html("用户名可以使用!"); } } ); } } </script> <body> <form action="" id="form1"> <table> <tr> <td>用 户 名:</td> <td><input type="text" name="uname" id="uname" onblur="validate();" /> <font color="#c00fff">*</font></td> <td> <div id="unameDiv" style="display: inline"></div> </td> </tr> </table> </form> </body>
$.post()
- 语法格式
$.post(url,data,success(resp,status,xhr), dataType);
- 常用参数
参数名 |
说 明 |
String url |
规定将请求发送到哪个URL |
Object data 或 String data |
可选。规定连同请求发送到服务器的数据 |
function success( Object result, String status, XMLHttpRequest xhr) |
可选。请求成功后调用的函数 参数result:可选,服务器返回的结果数据 参数status:可选,请求的状态 参数xhr:可选 |
String dataType |
可选。预期服务器返回的数据类型,可用类型有:XML、HTML、Script、JSON、JSONP、text |
- 示例代码:
<script src="script/jquery-1.12.4.js" type="text/javascript"></script> <script type="text/javascript"> /** 用户名验证函数*/ function validate() { var $uname = $("#uname").val(); if ($uname == "" || $uname == null) {//客户端非空验证 $("#msg").html("用户名为空!"); } else { $.post("Server02.php",{"uname":$uname},function(result){ if($.trim(result)=="false"){ $("#msg").html("用户名不可用!"); }else if($.trim(result)=="true"){ $("#msg").html("用户名可用!"); } }); } } </script>
load()
- 语法格式
$(selector).load(url ,data,function(result, status, xhr));
- 常用参数
参数名 |
说 明 |
String url |
规定将请求发送到哪个URL |
Object data 或 String data |
可选。规定连同请求发送到服务器的数据 |
function callback( Object result, String status, XMLHttpRequest xhr) |
可选。请求完成后调用的函数 参数result:服务器返回的结果数据 参数status:请求的状态 |
- 主要代码示范
<script type="text/javascript"> function validate(){ var uname = $("#uname").val(); if(uname==null || uname==""){ $("#unameDiv").html("用户名不能为空!"); }else{ $("#unameDiv").load('D05Server.php','uname='+uname); } } </script> <body> <form action="" id="form1" > <table> <tr> <td>用 户 名:</td> <td> <input type="text" name="uname" id="uname" onblur="validate();" /> <font color="#c00fff">*</font> </td> <td> <div id="unameDiv" style="display: inline"></div> </td> </tr> </table> </form> </body>
上机练习3:使用$.get()、$.post()、load()方法实现异步检查注册邮箱是否已经存在。重新实现上机练习1。
JSON
JSON简介
- JSON(JavaScript Object Notation)
一种轻量级的数据交换格式。
Javascript和PHP都能操作的共同类型的数据。
通常用于在客户端和服务器之间传递数据。
例如:
{"id":4,"name":"梅西","pwd":"6666","role":"访客"}
- JSON优点
JSON出现之前的数据交互方式: XML。XML难于解析,体积比较大,读写不够灵活。
JSON优点:轻量级交互语言,结构简单易于解析。
JSON定义
- JSON对象
语法格式:var jsonObject={key:value,key:value,…}
示例:var andy={“name”:”张三”,”age”:30,”gender”:”男”}
- JSON数组
语法格式:var jsonArr={value1,value2,…}
示例:
var employees=[
{“name”:”张三”,”age”:30,”gender”:”男”},
{“name”:”李四”,”age”:20,”gender”:”男”},
{“name”:”小郭”,”age”:31,”gender”:”男”}]
示例
问题:定义JSON格式数据并在页面输出
问题分析:
- 定义JSON格式的user对象,并在id为objectDiv的DIV元素中输出
- 定义JSON格式的字符串数组,并在id为arrayDiv的DIV元素中输出
- 定义JSON格式的user对象数组,并在id为objectArrayDiv的DIV元素中使用<table>输出
示例代码:
<script src="js/jquery-1.11.3.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { //1、定义JSON格式的user对象,并在id为objectDiv的div中输出 var user = {"id":1,"name":"张三","pwd":"000" }; $("#objectDiv").append("ID:"+user.id+"<br>") .append("用户名:"+user.name+"<br>") .append("密码:"+user.pwd+"<br>"); //2、定义JSON格式的字符串数组,并在id为arrayDiv的div中输出 var ary = ["中","美","俄"]; for(var i=0;i<ary.length;i++) { $("#arrayDiv").append(ary[i]+" "); } //3、定义JSON格式的user对象数组,并在id为objectArrayDiv的div中使用<table>输出 var userArray = [ {"id":2,"name":"admin","pwd":"123"}, {"id":3,"name":"詹姆斯","pwd":"11111"}, {"id":4,"name":"梅西","pwd":"6666"} ]; $("#objectArrayDiv").append("<table>") .append("<tr>") .append("<td>ID</td>") .append("<td>用户名</td>") .append("<td>密码</td>") .append("</tr>"); for(var i=0;i<userArray.length;i++) { $("#objectArrayDiv").append("<tr>") .append("<td>"+userArray[i].id+" </td>") .append("<td>"+userArray[i].name+" </td>") .append("<td>"+userArray[i].pwd+"</td>") .append("</tr>"); } $("#objectArrayDiv").append("</table>"); }); </script> <body> 一、JSON格式的user对象: <div id="objectDiv"></div> <br> 二、JSON格式的字符串数组: <div id="arrayDiv"></div> <br> 三、JSON格式的user对象数组: <div id="objectArrayDiv"></div> </body>
使用JSON格式数据注意事项:
- json的分隔符(delimiter)只允许使用双引号,不能使用单引号。
- json名值对的"名"(冒号左边的部分),任何情况下都必须使用双引号。
- 最后一个值之后不能添加逗号(trailing comma)。
- 如下所示:
使用jQuery处理JSON数据
- $.getJSON()函数
异步发送请求到服务器端,并以JSON格式封装客户端与服务器间传递数据。即发送JSON到服务器,也接受从服务器传递过来的JSON。
- 语法格式
$.getJSON(url,data,success(result,status, xhr))
- 常用参数
参数名 |
说 明 |
String url |
将请求发送到哪个URL |
Object data 或 String data |
可选。连同请求发送到服务器的数据 |
function success( Object result, String status, XMLHttpRequest xhr) |
可选。请求成功后运行的函数 参数result:服务器端响应的结果数据 参数status:请求的状态 |
- 示例:使用$.getJSON实现用户名验证
客户端代码示例:
<script type="text/javascript"> function validate(){ var uname = $("#uname").val(); if(uname==null || uname==""){ $("#unameDiv").html("用户名不能为空!"); }else{ $.getJSON('D07Server.php',{uname:uname},function(data){ $("#unameDiv").html(data.msg); }); } } </script> </head> <body> <form action="" id="form1"> <table> <tr> <td>用 户 名:</td> <td><input type="text" name="uname" id="uname" onblur="validate();" /> <font color="#c00fff">*</font></td> <td> <div id="unameDiv" style="display: inline"></div> </td> </tr> </table> </form> </body>
服务器端代码示例:
$uname = $_GET["uname"]; if("admin"==$uname){ echo "{"flag":true,"msg":"<font color='red'>用户名已被使用!</font>"}"; }else{ echo "{"flag":false,"msg":"<font color='green'>用户名可以使用!</font>"}"; }
如何使用get()和post()等方法处理JSON格式字符串?
方案1:使用parseJSON函数
jQuery提供了$.parseJSON(jsonstring)函数用于将JSON格式字符串转换为JSON对象。
示例代码:
$.get("Server05.php", "uname=" + $uname, function (result) { var jsresult = $.parseJSON(result);//把json格式的字符串转换为JSON对象 alert(jsresult); });
方案2:指定get和post方法返回json格式数据
通过get和post方法的第四个参数指定服务器返回数据格式。、
$.get("Server05.php", "uname=" + $uname, function (result) { alert(result); },"json");
上机练习4:使用$.getJSON()方法实现异步检查注册邮箱是否已经存在,验证结果返回一段JSON格式字符串,在客户端的回调方法中将返回的JSON对象信息显示到页面。重新实现上机练习1。
PHP的JSON函数
PHP处理JSON数据的相关函数有四个:
- json_decode — 对 JSON 格式的字符串进行解码
- json_encode — 对变量进行 JSON 编码
- json_last_error_msg — Returns the error string of the last json_encode() or json_decode() call
- json_last_error — 返回最后发生的错误
json_encode
1.概要
作用:对变量进行 JSON 编码
语法格式:
string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )
返回字符串,包含了 value 值 JSON 形式的表示。
编码受传入的 options 参数影响,此外浮点值的编码依赖于 serialize_precision。
参数说明:
value:待编码的 value ,除了resource 类型之外,可以为任何数据类型。所有字符串数据的编码必须是 UTF-8。
options:转换选项,常用的有JSON_FORCE_OBJECT(转换为对象),JSON_UNESCAPED_UNICODE(使用原字符编码转换)。
depth:设置最大深度。 必须大于0。
返回值:成功则返回 JSON 编码的 string 或者在失败时返回 FALSE 。
2.数组转换为JSON对象
由于js不支持关联数组,所以json_encode()只将索引数组(indexed array)转为数组格式(js数组格式),而将关联数组(associative array)转为对象格式。
示例一:将索引数组转换为数组
$arr=array("大一","大二","大三","大四","实习"); $jsonString=json_encode($arr,JSON_UNESCAPED_UNICODE); echo $jsonString;
输出JS格式数组:
JSON_UNESCAPED_UNICODE:JSON默认使用unicode编码,该选择则选使用原数组字符编码(原数组为UTF-8编码)。否则乱码。
示例二:关联数组转换为JSON格式对象
$arr=array("s1"=>"大一","s2"=>"大二","s3"=>"大三","s4"=>"大四","g1"=>"实习","time"=>2018,1314=>"318寝室"); $jsonString=json_encode($arr,JSON_UNESCAPED_UNICODE); echo $jsonString;
输出JSON对象:
示例三:多维数组转换为JSON对象数组
例如从数据库中使用PDOStatement对象的fetchAll()方法读出的二维数组:
$opt = array(PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_ORACLE_NULLS => true);//持久化优化 //*** try { $dbh = new PDO($dsn, $user, $password, $opt); //删除数据 $sql = "SELECT * FROM grade "; $pdostmt = $dbh->query($sql); $result = $pdostmt->fetchAll(); $jsonString = json_encode($result, JSON_UNESCAPED_UNICODE); echo $jsonString; } catch (PDOException $e) { echo "持久化异常:" . $e->getMessage(); }
输出JSON对象数组:
[{"gradeid":1,"gradename":"大一"},{"gradeid":2,"gradename":"大二"},{"gradeid":3,"gradename":"大三"},{"gradeid":4,"gradename":"大四"}]
3.类转换为JSON对象
示例一:单个对象和对象数组转换为JSON对象
定义学生类:
class Student { public $studentNo;//学号 private $studentName;//姓名 protected $gender;//性别 public function __construct($studentNo, $studentName, $gender) { $this->studentNo = $studentNo; $this->studentName = $studentName; $this->gender = $gender; } public function __get($propertyName) { return $this->$propertyName; } public function __set($propertyName, $propertyValue) { $this->$propertyName = $propertyValue; } public function method() { echo "This is Student Object"; } }
实例化一个学生和一个学生数组,分别输出JSON编码输出:
$zs=new Student(2018001,"张三","男"); $students=array( new Student(2018001,"张三","男"), new Student(2018002,"李四","男"), new Student(2018003,"王五","女") ); echo "PHP单个对象转换为JSON对象:".json_encode($zs,JSON_UNESCAPED_UNICODE); echo " "; echo "PHP对象数组转换为JSON对象数组:".json_encode($students,JSON_UNESCAPED_UNICODE);
输出结果:
PHP单个对象转换为JSON对象:{"studentNo":2018001} PHP对象数组转换为JSON对象数组:[{"studentNo":2018001},{"studentNo":2018002},{"studentNo":2018003}]
说明:
类中除了public修饰的成员变量,其他成员变量和成员方法未参与JSON编码。
json_decode
作用:将JSON格式文本转换为相应的PHP数据结构。
语法格式:
mixed json_decode ( string $json [, bool $assoc = FALSE [, int $depth = 512 [, int $options = 0 ]]] )
参数说明
json:待解码的 json string 格式的字符串。这个函数仅能处理 UTF-8 编码的数据。
assoc:当该参数为 TRUE 时,将返回 array 而非 object 。
depth:指定递归深度。
options:JSON解码的掩码选项。 现在有两个支持的选项。 第一个是JSON_BIGINT_AS_STRING, 用于将大整数转为字符串而非默认的float类型。第二个是 JSON_OBJECT_AS_ARRAY, 与将assoc设置为 TRUE 有相同的效果。
示例一:将JSON对象格式的文本转换为PHP对象
$jsonString='{"studentNo":2018001,"studentName":"张三"}'; $student=json_decode($jsonString); echo $student->studentNo." ".$student->studentName;
输出:
注意:此例中$jsonString中总是被默认转换为Object类型。如果需要转换为关联数组,则需要json_decode()需要第二个参数:$student=json_decode($jsonString,true);
示例二:将JSON对象数组格式的文本转换为PHP对象
$jsonString='[{"studentNo":2018001,"studentName":"张三"},{"studentNo":2018002,"studentName":"李四"},{"studentNo":2018003,"studentName":"王五"}]'; $students=json_decode($jsonString); foreach ($students as $student) { echo $student->studentNo . " " . $student->studentName." "; }
输出:
客户端解析JSON数据
示例代码
$(function(){ $('#btn').click(function(){ $.ajax({ type: "GET", url: "server.php", data: {uname:$("#username").val(), uage:$("#ugage").val()}, dataType: "json", success: function(data){ $.each(data, function(i, n){ alert(i+"======"+n); }); } }); }); });
$.each()函数
不同于JQuery对象的each()方法,它是一个全局函数,不操作JQuery对象,示例中以JSON对象数组作为参数,以一个回调函数作为第2个参数。回调函数拥有两个参数:第1个为对JSON对象数组的索引,第2个为对应JSON对象数据。