复习:
AJAX:向服务器发起异步HTTP请求,接收处理返回的响应消息,目标是实现页面在无刷新无提交情况下页面内容的局部更新。
使用AJAX发起两种请求消息:
GET://1 //2 //3 //4
POST : //1 //2 //3 //3.5 //4
使用AJAX接收五种响应消息:
(1)text/plain
服务器端:
header('Content-Type: text/plain');
echo 'succ';
客户端:
if(xhr.responseText==='succ'){ ... }
(2)text/html
服务器端:
header('Content-Type: text/html');
echo "<tr><td>$data</td></tr>";
客户端:
tbody.innerHTML = xhr.responseText
(3)application/javascript
服务器端:
header('Content-Type: application/javascript');
echo "alert($data); f1(); f2($data)";
客户端:
eval( xhr.responseText )
(4)application/xml
服务器端:
header('Content-Type: application/xml');
echo "<bookList><book>$b</book></bookList>";
客户端:
var document = xhr.responseXML
(5)application/json
服务器端:
header('Content-Type: application/json');
//echo "[ {"bname":"","price":35.5},{} ]";
$list = ...;
echo json_encode($list);
客户端:
var obj = JSON.parse( xhr.responseText )
练习: 实现学生查询系统
(1)编写SQL:qinghua.sql,表qh_class( cid, cname, count ),插入三个班级(10/20/30);qh_student(sid, sname, score, classId),插入八九行记录
(2)编写PHP:class_select.php,向客户端输出所有的班级信息,以JSON格式: [{},{},{}]
(3)编写HTML:qinghua.html,页面加载完成(window.onload)后,异步请求,获取所有的班级信息,填充在一个select中
<select> 10:15
<option value="10">软件0801班</option>
</select>
(4)编写PHP:student_select.php,接收客户端提交的cid,返回指定班级中的学生数据,以JSON格式: [{},{},{}]
(5)修改HTML:qinghua.html,为select做事件绑定,监听选项改变,异步请求选定班级中的学生,显示在table中
<table>
<thead></thead>
<tbody></tbody>
</table>
今日目标:
(1)使用jQuery的AJAX封装函数——六个
1.使用jQuery的AJAX封装函数之一——load()
使用方法:
$('选择器').load(URL, [请求数据], [成功后的回调函数])
$('ul').load('search_suggest.php');
含义说明:
向指定的URL发起异步请求;若有请求数据,就是POST请求,否则就是GET请求;获取服务器端返回HTML片段响应,设置为当前选定元素的innerHTML。
使用限制:
(1)服务器返回的必需是HTML片段;
(2)服务器端返回的数据会替换已有数据!
案例演示: 异步加载多个页面完全一样的页头/页尾
(1)编写header.php,只含有页头中的DIV片段
(2)编写footer.php,只含有页尾中的DIV片段
(3)编写jdindex.php,内容:
<body>
<div id="header"></div>
<div id="main">XXXXXX</div>
<div id="footer"></div>
</body>
待页面加载完后,异步请求页头,放在#header中
待页面加载完后,异步请求页尾,放在#footer中
2.使用jQuery的AJAX封装函数之二——$.get()
使用方法:
$.get(URL, [请求数据], 响应成功后的回调函数)
$.get('delete.php', 'sid=8', function(txt){ if(txt==='succ'){} })
$.get('delete.php', {sid:8}, function(txt, msg, xhr){ if(txt==='succ'){} })
含义作用:
向指定的URL发起异步的GET请求,把请求数据追加在URL的后面;服务器给出了成功的响应会自动调用第三个参数——doResponse。
提示:$.get会根据服务器端返回的响应消息内容类型自动决定如何处理,如applicatoin/json,会自动调用JSON.parse(xhr.responseText)进行解析!
案例演示:实现异步的学生记录的删除
案例演示:异步级联下拉列表 $.get()
(1)编写SQL:qinghua.sql,产品类别表 qh_type( tid, tname ),插入三行数据(10-相机、20-洗衣机、30-手机),生产厂家表qh_producer( pid, pname, typeId ),插入若干记录;产品型号表 qh_model( mid, mname, producerId )
(2)编写PHP:type_select.php,向客户端返回所有的产品类型,以JSON格式
(3)编写PHP:producer_select.php,根据客户端提交的typeId,向客户端返回该类型所有的厂家,以JSON格式
(4)编写PHP:model_select.php,根据客户端提交的producerId,向客户端返回该厂家生产的所有型号,以JSON格式
(5)编写HTML,product.html,
当页面加载完成后,异步请求所有的“产品类型”;
当产品类型选项发生改变后,异步请求对应的“生产厂家”;
当生产厂家选项发生改变后,异步请求该厂家的“产品型号”
3.使用jQuery的AJAX封装函数之三——$.post()
使用方法:
$.post(URL, 请求数据, 响应成功后的回调函数)
含义作用:
向指定的URL发起异步的POST请求,把请求数据放置在请求主体——无需手写3.5步;服务器给出了成功的响应会自动调用第三个参数——doResponse。
提示:$.post会根据服务器端返回的响应消息内容类型自动决定如何处理,如applicatoin/json,会自动调用JSON.parse(xhr.responseText)进行解析!
案例演示:实现异步的用户注册
(1)编写SQL:qinghua.sql,用户信息表 qh_user(uid, uname,upwd)
(2)编写PHP:user_add.php,接收客户端提交的uname和upwd,返回succ或err
(3)编写HTML:user_add.html,没有表单,只有两个输入域+BUTTON按钮,点击后异步提交给服务器 $.post(url, {uname:xx, upwd:xx}, fn)
4.使用jQuery的AJAX封装函数之四——$.getScript()——了解
使用方法:
$.getScript(URL, [请求数据], [响应成功后的回调函数])
$.getScript('x.php')
含义作用:
向指定的URL发起异步的GET请求,把请求数据放置在url后面;服务器给出了成功的响应会自动执行eval( xhr.responseText )。
使用限制:
要求服务器必须返回application/javascript!即使不是,也会强制调用eval(xhr.responseText)进行执行!而$.get()可以实现同样的功能,却可以根据服务器端的响应头来决定是否调用eval()
5.使用jQuery的AJAX封装函数之五——$.getJSON()——了解
使用方法:
$.getJSON(URL, [请求数据], 响应成功后的回调函数)
$.getJSON('x.php', function(obj){})
含义作用:
向指定的URL发起异步的GET请求,把请求数据放置在url后面;服务器给出了成功的响应会自动执行JSON.parse( xhr.responseText )。
使用限制:
要求服务器必须返回application/json!即使不是,也会强制调用JSON.parse(xhr.responseText)进行执行!而$.get()可以实现同样的功能,却可以根据服务器端的响应头来决定是否调用JSON.parse()
上述五个函数的通病:只能处理成功的响应消息!如果服务器端返回了错误的响应消息(如404)上述五个函数不会有任何的提示——没有相关的回调函数!
面试题:如何使用jQuery的AJAX相关函数,监听失败的响应消息??——使用万能AJAX封装函数:$.ajax |
6.使用jQuery的AJAX封装函数之六——$.ajax()——重点
使用方法:
$.ajax( {
type: 'GET', //POST/PUT/DELETE...
url: 'x.php',
data: 'k=v&k=v', //{k:v, k:v}
beforeSend: fn, //在请求发送前的回调
success: fn, //响应成功后的回调
error: fn, //响应失败后的回调
complete: fn //响应完成后(不论成败)的回调
} )
成功的调用: beforeSend() => success() => complete()
失败的调用: beforeSend() => error() => complete()
对应于原生AJAX: //1 var xhr = new XMLHttpRequest(); //2 xhr.onreadystatechange = function(){ if(xhr.readyState===4){ if(xhr.status===200){ success(); }else { error(); } complete() } } //3 xhr.open() beforeSend(); //4 xhr.send() |
1. JS中如何处理JSON字符串
把JSON格式的字符串解析为JS对象:
var str = '{"ename":"Tom", "age":20}';
var obj = JSON.parse(str); //方法1
var obj = eval( '('+str+')' ); //方法2,不推荐使用
把JS对象编码为JSON字符串:
var obj = {ename:'Tom', age: 20};
var str = JSON.stringify(obj);
-ify: 使变为..., sheepify stoneify frogify
=================================
PHP中把数组编码为JSON字符串:
$list = [{},{},{}];
$str = json_encode( $list );
PHP中JSON字符串解析为PHP数组/对象:
$str = '{"ename":"Tom", "age":20}';
$obj = json_decode( $str );
2.面试题:跨域请求和JSONP
Cross Domain Request:从一个资源请求另一个资源,二者所在的请求地址不同,域名不同、端口号不同、请求协议不同。
http://www.tmooc.cn/list.html
http://www.tedu.cn/student_select.php
提示:localhost和127.0.0.1也算跨域!
浏览器允许跨域请求的情形:
IMG、LINK、SCRIPT、IFRAME ...
浏览器禁止跨域请求的情形:
XHR —— 浏览器处于安全考虑,禁用了XHR的跨域请求(其实服务器给出了响应消息,但浏览器不让使用)
面试题:我们公司项目很大,页面很多,出于性能考虑,把静态资源(html等)放在http://static.tmooc.cn服务器上了,把动态资源(php)放在http://dynamic.tmooc.cn服务器上了,如何让一个x.html异步请求x.php呢? |
如何解决浏览器的XHR跨域请求限制 —— 八种方案:
(1)
(2)
(3)
(4)
(5)
(6)
(7) 修改响应消息头部,添加Access-Control-Allow-Origin头部
(8) 使用JSONP——非常巧妙
JSON: JavaScript Object Notation,是一种字符串数据格式(羊肉)。
JSONP:JSON with Padding,填充式JSON,与JSON完全两码事,是一种使用JSON数据的方式(把羊肉红烧)。意思是在JSON字符串左右添加函数名: doResponse( {"ename":"Tom", "age":20} );
JSONP是专用于解决XHR跨域限制一种手段。基本原理:使用动态创建的一个SCRIPT标签代替XHR发起异步请求,要求服务器必须返回application/javascript,立即在客户端执行——要执行的函数本体在客户端浏览器中声明。
<script src="x.php" async></script>
面试题:jQuery中如何使用JSONP发起异步请求:
(1) $.getJSON()
用途1:使用XHR发起异步请求(不能跨域)
$.getJSON('x.php', doResponse)
用途2:使用JSONP发起跨域异步请求
$.getJSON('http://跨域地址/x.php?callback=?', doResponse)
(2) $.ajax()
用途1:使用XHR发起异步请求(不能跨域)
$.ajax({ })
用途2:使用JSONP发起跨域异步请求
$.ajax({ dataType: 'jsonp' })