11-Ajax详解
Ajax的基本概念及使用
同步&异步
- 同步:必须等待前面的任务完成,才能继续后面的任务;
- 异步:不受当前主要任务的影响。
- 举个例子:
- 同步:我们在银行排队时,只有等到你了,才能够去处理业务;
- 异步:我们在排队的时候,玩王者农药的先后顺序是各不相关的。
异步更新网站
-
当我们访问一个普通的网站时,当浏览器加载完:HTML、CSS、JS以后网站的内容就固定了。如果网站内容发生更改必须刷新页面才能够看到更新的内容。
-
网站内容更新:常规的网站内容更新,必须通过刷新才能显示新内容。
-
异步更新:
-
我们在访问新浪微博时,当你看到一大半了,会自动帮我们加载更多的微博,同时之前的页面并没有刷新。
Ajax概念
-
在不刷新页面的情况下,“偷偷”的发送数据给服务器,通过发出http请求。
-
在没有学习Ajax以前,如果想要发出http请求(发出请求报文):
-
页面会刷新;
-
后果:如果网速很慢,刷新页面势必会重新加载;造成不必要的时间浪费;
-
一些极少量的信息想要提交给服务器,也没有必要刷新整个页面。
-
写法:是通过js在
浏览器端
帮我们预定义的一个异步对象来完成的。 -
事例:当我们正在排队的时候,可以通过手机去干一些其他的事情。
-
在浏览器中,我们也能够不刷新页面,通过ajax的方式去获取一些新的内容,类似网页有微博、朋友圈、邮箱等。
-
单词解释:
Asynchronous Javascript And XML(异步JavaScript和XML)
,他并不是凭空出现的新技术,而是对于现有技术的结合:核心是js对象XMLHttpRequest
。
XMLHttpRequest
- ajax使用的依旧是HTTP请求,那么让我们来回忆一下一个完整的HTTP请求需要什么:
- 请求的网址,方法get/post;
- 提交请求内容数据、请求主体等;
- 接收响应回来的内容。
写Ajax的步骤
- 先写html页面,通过某种条件发出ajax请求;
- 写在php页面,处理发过来的请求;
- 再回到浏览器异步对象的onreadystatechange事件中,去处理返回的内容。
发送Ajax请求,使用的是js
- 五步使用法:
- 创建异步对象:
var ajaxObj = new XMLHttpRequest();
- 使用
open
方法设置请求的参数:- ajaxObj.open('get','xxx.php');
- 参数1为请求的方法,参数2为请求的url;
- 发送请求:(发送请求报文)
- ajaxObj.send();
- 注册事件:(服务器返回响应报文)
- 状态改变时就会调用,如果要在数据完成请求回来的时候才调用,我们需要手动的写一些判断的逻辑;
ajaxObj.onreadystatechange = function (){
//为了保证数据完整回来,我们一般会判断两个值
if (ajaxObj.readyState==4 && ajaxObj.status==200){
//在注册事件中,获取返回的内容,并修改页面的显示
}
}
-
在注册的事件中,获取返回的内容,并修改页面的显示。
浏览器与服务器的关系
- 示例代码:GET(get的数据,直接在请求的url中添加即可)
- html中的代码:
<body>
<input type="text" class="user">
<button>发送请求</button>
<script>
document.querySelector("button").onclick = function () {
//1.创建异步对象
var xhr = new XMLHttpRequest();
//2.设置method、url等参数
var userName = document.querySelector(".user").value;
xhr.open("get","03-XMLHttpRequest.php?name="+userName);
//3.发送数据
xhr.send();
//4.绑定事件
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==200){
//5.在绑定事件中获取返回的数据,显示页面
console.log(xhr.responseText);
}
}
}
</script>
</body>
- php中的代码:
<?php
echo $_GET['name'].",欢迎你";
?>
- 示例代码:POST
- 有两点不同
1.发送的数据写在send方法中;
2.必须要在open和send之间添加setRequestHeader("Content-type","application/x-www-form-urlencoded"); - html中的代码:
<body>
<input type="text" class="user">
<button>发送请求</button>
<script>
document.querySelector("button").onclick = function () {
//1.创建异步对象
var xhr = new XMLHttpRequest();
//2.设置method、url等参数
xhr.open("POST","03-XMLHttpRequest.php");
//如果使用post发送数据,必须要添加如下内容,修改发送给服务器的请求报文的内容。form表单使用post发送数据不需要设置,因为form表单默认会进行转换
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//3.发送请求,发送请求的数据写在send方法中
//格式 name=jiang & age=18
var userName = document.querySelector(".user").value;
xhr.send("name="+userName);
//4.绑定事件
xhr.onreadystatechange = function () {
//5.在绑定事件里获取数据,展示页面
if (xhr.readyState==4 && xhr.status==200){
console.log(xhr.responseText);
}
}
}
</script>
</body>
- php中的代码:
<?php
echo $_POST["name"].",你好";
?>
- 实际开发中,get和post的选取:
由后台程序员以文档或者口头形式告知;
如果不考虑提交文件,那么get/post的作用基本一致,只是写法不同;
自己写demo的时候,随便选取哪一个使用。
练习:异步切换明星头像
XMLHttpRequest_API讲解
创建XMLHttpRequest对象
(兼容性写法):
- 新版本浏览器:
var xml=new XMLHttpRequest();
- IE5和IE6:
var xml=new ActiveXObject("Microsoft.XMLHTTP");
- 考虑兼容性创建Ajax对象
var request ;
if(XMLHttpRequest){
// 新式浏览器写法
request = new XMLHttpRequest();
}else{
//IE5,IE6写法
request = new ActiveXObject("Microsoft.XMLHTTP");
}
发送请求:
方法 | 描述 |
---|---|
open(method,url,async) | 规定请求的类型、URL 以及是否异步处理请求。<ul><li>method:请求的类型;GET 或 POST;</li><li>url:文件在服务器上的位置;</li><li>async:true(异步)或 false(同步)</li></ul> |
send(string) | 将请求发送到服务器。string:仅用于 POST 请求 |
POST请求注意点:
- 如果想要像
form表单
提交数据那样使用POST
请求,需要使用XMLHttpRequest对象
的setRequestHeader()
方法来添加HTTP头
。然后在send()
方法中添加想要发送的数据:
xmlhttp.open("POST","ajax_test.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Bill&lname=Gates");
onreadystatechange事件
- 当服务器给予我们反馈时,我们需要实现一些逻辑
属性 | 描述 |
---|---|
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化:<ul><li>0:请求未初始化;</li><li>1:服务器连接已建立;</li><li>2:请求已接收;</li><li>3:请求处理中;</li><li>4:请求已完成,且响应已就绪。</li></ul> |
status | 200: "OK";404: 未找到页面 |
服务器响应内容
- 如果响应的是普通字符串,使用
responseText
,如果响应的是XML,使用responseXML
;
属性 | 描述 |
---|---|
responseText | 获得字符串形式的响应数据。 |
responseXML | 获得 XML 形式的响应数据。 |
服务器
- Apache;
- web服务端开发的语言;
- 设置访问的网站:
- 设置网站根目录;
- 往网站的目录中拷贝文件即可:
- .html:如果存在该页面,会原封不动的返回给用户;
- .php:会将php中的代码执行完,将结果返回给浏览器。
php如何读取文本数据
- 目的:实现数据和逻辑代码分离;
- PHP之所以被称为“最好的编程语言”:使用十分方便,基本上我们能够想到的功能,都帮我们封装成了方法:
file_get_contents(文件路径);
Ajax数据传输XML
XML简介
- XML:指可扩展标记语言
EXtensible Markup Language
,他设计的时候是用来传递数据的,虽然格式跟HTML类似.。 - xml示例:下面是一个XML示例
<?xml version="1.0" encoding="UTF-8"?>
<singer>
<name>周杰伦</name>
<age>18</age>
<skill>途牛</skill>
</singer>
- XML是纯文本,这点跟HTML很像,所以我们可以用任何的文本编辑软件去打开编辑它。
XML语法
- 虽然看起来跟HTML类似,但是XML的语法有些需要注意的,更为详细的可以查阅:http://www.w3school.com.cn/xml/index.asp。
- XML声明:
第一行
是XML的声明,指定XML版本
(1.0)以及使用的编码
(UTF-8万国码):
<?xml version="1.0" encoding="UTF-8"?>
- 自定义标签,XML中没有默认的标签,所有的标签都是我们自定义的;
- 注:不要使用数字开头,不要使用中文。
<!-- 下列标签都是被允许的 -->
<fox></fox>
<name></name>
- 双标签XML中没有单标签,
都是双标签
;
<haha>标签内</haha>
- 根节点:XML中必须有一个
根节点
,所有的子节点都放置在根节点下
<root>
<name></name>
</root>
- XML属性:跟HTML一样,XML的标签里面也能够添加属性
type = 'text'
,但是不建议这样用,而是使用标签的方式来表述内容(下半部分代码)
<!-- 使用属性配合标签表述信息 -->
<person sex="female">
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
<!-- 使用标签来表述信息 -->
<person>
<sex>female</sex>
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
XML解析
- 因为XML就是标签,所以直接用解析Dom元素的方法解析即可;
- html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<person id='personXML'>
<name>fox</name>
<age>18</age>
<skill>小花花</skill>
</person>
</body>
</html>
- 获取方法:
<script type="text/javascript">
var xmlObj = document.getElementById("personXML");
var name = xmlObj.getElementsByTagName('name')[0].innerHTML;
console.log(name);
</script>
PHP中设置Header
- 在php中如果要使用
xml传输数据
,需要使用header()
设置返回的内容为xml:
header('content-type:text/xml;charset=utf-8');
- 从php中获取xml内容,html中的代码如下:
<script type="text/javascript">
document.querySelector('#getXML').onclick = function () {
var ajax = new XMLHttpRequest();
ajax.open('get','get_XMl.php');
ajax.send();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status==200) {
// 如果 返回的是 xml文件
console.log(ajax.responseText);
// 异步 对象中 有另外一个属性 用来专门获取 xml
// xml对象 在浏览器端 就是一个 document对象
// 解析时 可以直接使用 querySelector 或者 getElementById等 document对象 有的语法
console.log(ajax.responseXML);
console.log(ajax.responseXML.querySelector('name').innerHTML);
// 下面这个 页面文档对象,和ajax.responseXML一模一样, 如果要获取某个标签,使用同样的方法
console.log(window.document);
}
}
}
</script>
- php:
<?php
header('content-type:text/xml;charset=utf-8');
$text = file_get_contents("01-getFile-xml.xml");
echo $text;
?>
- xml:
<?xml version="1.0" encoding="UTF-8" ?>
<yijiang>
<name>yijiang</name>
<age>20</age>
<sex>男</sex>
</yijiang>
Ajax中获取xml:
-
浏览器:
-
通过
xhr.responseXML
获取返回的xml值; -
(如果通过xhr.responseText获取,返回的是字符串)。
-
服务器:
-
准备一个xml文件;
-
php中获取xml文件内容,并返回(注意要设置header:
header('content-type:text/xml;charset=utf-8');
)
实际开发中xml用的频率不是很高,敲两遍就可以了。
案例:重写明星头像
- html中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change</title>
<style>
table{
width: 400px;
margin: 20px auto;
border: 1px solid #000;
}
td{
border: 1px solid #000;
}
img{
height: 200px;
width: 200px;
}
</style>
</head>
<body>
<script>
//1.
var xhr = new XMLHttpRequest();
//2.
xhr.open("get","change-xml.php");
//3.
xhr.send();
//4.
xhr.onreadystatechange = function () {
//5.
if (xhr.readyState==4 && xhr.status==200){
var responseStars = xhr.responseXML;
var stars = responseStars.querySelector("stars").children;
console.log(stars[0].querySelector("name").innerHTML);
var str = "<table>";
for(var i=0; i<stars.length; i++){
str += "<tr>";
str += "<td>"+stars[i].querySelector("name").innerHTML+"</td>";
str += "<td>![]("+stars[i].querySelector("pic").innerHTML+")</td>";
str += "<td>"+stars[i].querySelector("description").innerHTML+"</td>";
}
str += "</table>";
document.body.innerHTML = str;
}
}
</script>
</body>
</html>
- php中:
<?php
header('content-type:text/xml;charset=utf-8');
echo file_get_contents('change-xml.xml');
?>
- xml中:
<?xml version="1.0" encoding="UTF-8" ?>
<stars>
<star>
<name>Angelababy</name>
<age>30</age>
<description>著名女演员</description>
<pic>images/baby.jpg</pic>
</star>
<star>
<name>mage</name>
<age>16</age>
<description>国际名模</description>
<pic>images/mage.jpeg</pic>
</star>
<star>
<name>wangge</name>
<age>18</age>
<description>大陆著名企业家</description>
<pic>images/shuaige.jpeg</pic>
</star>
</stars>
Ajax传输JSON
JSON语法
-
JSON(JavaScript Object Notation)
一种字符串格式;
是ECMAScript的子集,作用是进行数据的交换;
而且由于语法更为简洁,网络传输以及机器解析都更为迅速;
使用的最多,基本上所有的语言都有将JSON字符串转化为该语言对象的语法。 -
语法规则:
-
数据在键值对中;
-
数据由逗号分隔;
-
花括号保存对象;
-
方括号保存数组;
-
总结:属性名必须使用双引号包裹,属性值(数组除外)必须使用双引号包裹。
-
数据类型:
-
下列内容,无论是键还是值 都是用双引号包起来:
- 数字(整数或浮点数);
- 字符串(在双引号中);
- 逻辑值(true 或 false);
- 数组(在方括号中);
- 对象(在花括号中);
- null。
-
示例代码:下部分代码看起来类似于定义JavaScript对象
// 基本对象
{
"name":"fox",
"age":"18",
"sex":"true",
"car":null
}
// 数组
[
{
"name":"小小胡",
"age":"1"
},
{
"name":"小二胡",
"age":"2"
}
]
JSON解析
-
接下来演示如何使用
JavaScript
和PHP
对JSON
进行解析 -
基本使用步骤:
JSON图
JavaScript中
- 使用JSON对象:
-
JSON.parse()
方法:将JSON字符串
转化为JavaScript对象
; -
JSON.stringify()
方法:将JavaScript对象
转化为JSON字符串
; - 由于老式IE(8以下)浏览器中没有JSON对象,通过导入
JSON2.js框架
即可解决,框架获取地址为:JSON2.js_github地址(https://github.com/douglascrockford/JSON-js);
var Obj = {
name:"fox",
age:18,
skill:"撩妹"
};
console.log(Obj);
// 将JavaScript对象格式化为JSON字符串
var jsonStr = JSON.stringify(Obj);
console.log(jsonStr);
// 将JSON字符串转化为JavaScript对象
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj);
- 使用
eval()方法
:使用eval()方法需要注意的是,需要将内容使用()括号包裹起来
,如示例代码:
<script type="text/javascript">
var jsonStr ={
"name":"fox",
"age":18,
"skill":"撩妹"
};
var jsonObj = eval('('+jsonStr+')'); console.log(jsonObj);
</script>
PHP中
-
json_decode()
方法: -
将
json字符串
转化为php变量
; -
json_encode()
方法: -
将
php变量
转化为json字符串
。 -
示例代码:
<?php
header("Content-Type:text/html;charset=utf-8");
// json字符串
$jsonStr = '{"name":"yijiang","age":"18","skill":"歌神"}';
// 字符串转化为 php对象
print_r(json_decode($jsonStr));
echo "<br>";
// php数组
$arrayName = array('name' =>'littleFox' ,'age' => 13 );
// php对象 转化为 json字符串
print_r(json_encode($arrayName));
?>
- 输出结果为:
stdClass Object ( [name] => yijiang [age] => 18 [skill] => 歌神 )
{"name":"littleFox","age":13}
解析JSON的完整写法:
- html中:此时js中获取返回的数据使用
xhr.responseText
<script>
//1.
var xhr = new XMLHttpRequest();
//2.
xhr.open("post","02-getFile-json.php");
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//3.
xhr.send();
//4.
xhr.onreadystatechange = function () {
//5.
if (xhr.readyState==4 && xhr.status==200){
var person = JSON.parse(xhr.responseText);
console.log(person);
//Object {name: "jiang", age: "16", skill: "撩汉"}
console.log(person.name); //jiang
console.log(person.age); //16
}
}
</script>
- php中:
<?php
echo file_get_contents("02-getFile-json.json");
?>
- json文件:
{
"name":"jiang",
"age":"16",
"skill":"撩汉"
}
Ajax工具函数封装
原生Ajax写法
-
原生使用Ajax主要分为五步,需要手写较多内容,如果每次我们使用Ajax都需要手写一遍,较为浪费时间,所以我们将公共代码抽取,封装为工具函数。
-
五步使用法:
-
建立
XMLHTTPRequest对象
; -
使用
open
方法设置和服务器端交互的基本信息:- 设置提交的网址、数据以及post提交的一些额外内容;
-
使用
send
设置发送的数据,开始和服务器端交互:- 发送数据;
-
注册事件:
- 当服务器回应我们了,我们想要执行什么逻辑;
-
更新界面:
- 在注册的事件中,获取返回的数据,更新界面。
-
示例代码:
GET
: -
get的数据,直接在请求的url中添加即可;
<script type="text/javascript">
// 创建XMLHttpRequest 对象
var xml = new XMLHttpRequest();
// 设置跟服务端交互的信息
xml.open('get','01.ajax.php?name=fox');
//发送数据
xml.send(null); // get请求这里写null即可,或者直接空
// 接收服务器反馈
xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
// 打印响应内容
alert(xml.responseText);
}
};
</script>
- 示例代码:
POST
:
<script type="text/javascript">
// 异步对象
var xhr = new XMLHttpRequest();
// 设置属性
xhr.open('post', '02.post.php' );
// 如果想要使用post提交数据,必须添加
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// 将数据通过send方法传递
xhr.send('name=fox&age=18');
// 发送并接受返回值
xhr.onreadystatechange = function () {
// 这步为判断服务器是否正确响应
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
</script>
抽取公共部分
-
重复步骤分析:
-
创建异步对象;
-
异步对象
open
,send
方法调用; -
post
方法需要添加HTTP
协议头文件; -
判断
Ajax
响应状态。 -
哪些部分是需要使用者自定义的:
1. 提交方法;
2. url地址;
3. 数据;
4. Ajax请求成功调用方法;
上述内容,应该是调用时,由用户传入的。
//优化,传入一个对象作为参数,对象中分别包含其它属性:method,url,data,success
function ajax_tool(params) {
//1.创建异步对象
var xhr = new XMLHttpRequest();
//2.3.
if (params.method == "get"){
if (params.data){
params.url += "?";
params.url += params.data;
}
//2.设置方法和url等
xhr.open(params.method,params.url);
//3.直接发送数据
xhr.send();
}else {
//2.
xhr.open(params.method,params.url);
//设置请求头
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
if (params.data){
//3.如果有数据,就发送数据
xhr.send(params.data);
}else {
//如果没有数据直接发送就好
xhr.send();
}
}
//4.注册事件
xhr.onreadystatechange = function () {
//5.在事件中获取数据,并修改界面
if (xhr.readyState==4 && xhr.status==200){
success(xhr.responseText);
}
};
}
案例:聊天机器人
jQuery中的Ajax
JQuery中Ajax使用
- JQuery作为最受欢迎的js框架之一,常见的Ajax已经帮助我们封装好了,只需要调用即可,更为详细的api文档可以查阅:w3cSchool_JQueryAjax:http://www.w3school.com.cn/jquery/jquery_ref_ajax.asp
$.get()
方法
使用`get`方法取代复杂 $.ajax 向服务器获取数据;
请求成功时可调用回调函数;
如果需要在出错时执行函数,请使用 $.ajax。
- 参数列表
参数 | 描述 |
---|---|
url | 必需。规定将请求发送的哪个 URL。 |
data | 可选。待发送 Key/value 参数 |
success(response) | 可选。规定当请求成功时运行的函数。额外的参数:response - 包含来自请求的结果数据。 |
dataType | 可选。规定预计的服务器响应的数据类型。默认地,jQuery 将智能判断。可能的类型:"xml"、"html"、"text"、"script"、"json"、"jsonp"。 |
-
关于dataType的说明:预计从服务端获取的数据类型,可以不写,如果写了,写成json,jq内部会帮我们进行JSON.parse()的转化。注意:
- 如果写成json,并且服务端返回的就是json格式字符串,在回调函数中获取的实参就是转化完成的js对象,直接按照对象使用即可;
- 如果写成json,但是返回的不是json格式的数据,那么将会返回null。
-
使用演示:
-
html代码:
<script src="jquery.min.js"></script>
<script>
$.get("01-jq-get.php",{name:"yijiang",des:"大帅比"},function (data) {
console.log(data);
});
</script>
- php代码:
<?php
echo $_GET['name']."是一个".$_GET['des'];
?>
- 结果:yijiang是一个大帅比
$.post
方法
使用 post 请求功能以取代复杂 $.ajax;
请求成功时可调用回调函数;
如果需要在出错时执行函数,请使用 $.ajax。
- 参数
参数 | 说明 |
---|---|
url | 必选。发送请求地址 |
data | 可选。待发送 Key/value 参数 |
callback | 可选。发送成功时回调函数 |
type | 可选。返回内容格式,xml, html, script, json, text, _default。 |
- html代码:
<script src="jquery.min.js"></script>
<script>
$.post("02-jq-post.php",{name:"mage",des:"大美妞"},function (data) {
console.log(data);
});
</script>
- php代码:
<?php
echo $_POST['name'].'是一个'.$_POST['des'];
?>
- 结果:mage是一个大美妞
$.getJSON
方法
在 jQuery 1.2 中,您可以通过使用JSONP形式的回调函数来加载其他网域的JSON数据:
如 "myurl?callback=?"。jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。
注意:此行以后的代码将在这个回调函数执行前执行。
- 参数:
参数 | 说明 |
---|---|
url | 必选,发送请求地址。 |
data | 待发送 Key/value 参数。 |
callback | 载入成功时回调函数。 |
- html中代码:
<script src="jquery.min.js"></script>
<script>
$.getJSON('02-jq-post.php',function (data) {
console.log(data);
})
</script>
- php中代码:
<?php
echo file_get_contents('xxx-json.json');
?>
- json文件代码:
{
"name":"jiang",
"age":"16",
"skill":"撩汉"
}
- 结果:Object {name: "jiang", age: "16", skill: "撩汉"}
格式化表单$('form').serialize()
我们在向服务器提交数据时,如果使用的是Ajax需要手动将数据格式化,转化成类似name=fox&age=18这样的格式,jQuery已经帮助我封装好了一个格式化数据的方法。
-
语法:
$(selector).serialize()
直接可以将form
中拥有name属性的表单元素的字,进行格式化。 -
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试jq_serialize方法</title>
<script type="text/javascript" src="./files/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#getFormInfo").on("click",function(){
var info = $("#testForm").serialize()
console.log(info);
})
})
</script>
</head>
<body>
<form id="testForm">
<input type="text" placeholder="您的姓名" name="userName">
<input type="text" placeholder="您的爱好" name="userHabbit">
<input type="text" placeholder="您最喜爱的食物" name="userHabbit">
</form>
<input type="button" value="格式化表单数据" id="getFormInfo">
</body>
</html>
- 演示效果:userName=yijiang&userHabbit=swimming&userHabbit=meat
$.ajax({})
方法
$.ajax()方法相比于前面的方法,拥有更为自由的定制性,可以替换$.get(),$.post()方法。
- 参数:
- 在w3cSchool_$.ajax_Api(http://www.w3school.com.cn/jquery/ajax_ajax.asp) 中,关于参数只有下列一个。实际使用中,传递的是一个对象;
- 而对象的属性在页面的下方(如图可略)
参数 | 描述 |
---|---|
settings | 可选。用于配置 Ajax 请求的键值对集合。可以通过 $.ajaxSetup() 设置任何选项的默认值。 |
-
回调函数
如果要处理$.ajax()得到的数据,则需要使用回调函数。beforeSend、error、dataFilter、success、complete。
beforeSend:在发送请求之前调用,并且传入一个XMLHttpRequest作为参数。
error:在请求出错时调用。传入XMLHttpRequest对象,描述错误类型的字符串以及一个异常对象(如果有的话)
dataFilter:在请求成功之后调用。传入返回的数据以及"dataType"参数的值。并且必须返回新的数据(可能是处理过的)传递给success回调函数。
success:当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。
complete:当请求完成之后调用这个函数,无论成功或失败。传入XMLHttpRequest对象,以及一个包含成功或错误代码的字符串。 -
示例代码:
-
这里演示的是常用的属性
$.ajax({
url:'01.php', //请求地址
data:'name=fox&age=18', //发送的数据
type:'GET', //请求的方式
success:function (argument) {}, // 请求成功执行的方法
beforeSend:function (argument) {}, // 在发送请求之前调用,可以做一些验证之类的处理
error:function (argument) {console.log(argument);}, //请求失败调用
});
案例:注册界面
模板插件
模版引擎简介
-
我们在使用
ajax
请求数据时,返回的如果是一个JSON格式
的字符串,我们需要将其包装到对应的HTML代码中
,再添加到页面上,才能看到效果。那么这个包装得过程有没有简单的方法呢? -
假设有如下数据(javascript中)
var obj = {
name:"fox",
age:18,
skill:"卖萌"
};
- 希望包装为:
<ul>
<li>姓名:fox</li>
<li>年龄:18</li>
<li>爱好:卖萌</li>
</ul>
-
定义模板,替换
: - 其间需要我们使用对象替换的位置为
<%= 属性名 %>
部分,如果可以:读取模板->传入对象->完成替换->返回html代码 实现这样的步骤,那么就能够完成我们的模板操作了
<ul>
<li>姓名:<%= name %></li>
<li>年龄:<%= age %></li>
<li>爱好:<%= skill %></li>
</ul>
模版插件原理
我们定义一段文本作为模板,读取文本,使用特殊的符号
<%= 属性名 %>
,通过正则表达式
找到这些特殊的符号进行替换,是不是就实现了这样的效果呢?
- 定义正则表达式:
- 想要匹配
<%= 属性名 %>
, 我们可以定义如下正则(javascript中):
JS中的RegExp对象:
创建:
创建方法1: var reg = new RegExp("正则")
创建方法2: var reg = /正则/; 推荐使用这种
使用:
reg.exec(string) 可以检测并返回字符串
正则含义:
<%:以 <% 开始
=\s* "="号之后有0个或多个空白字符
([^%>]+\S): 匹配除了%>以外的所有字符(至少1个)
\s*:0个或多个空白字符
%>:以%>结束
var reg = /<%=\s*([^%>]+\S)\s*%>/;
基本使用
- 定义好作为模板的文本;
- 使用
正则表达式
进行匹配替换即可。
// 定义文本
var str = '大家好,我叫<%= name %>,我今年<%= age %>,我的爱好为:<%= skill %>';
// 定义数据
var data = {
name: 'jiang',
age: 10,
skill:'打篮球'
};
// 快速的创建方法,好处,直接使用 \ 即可 不需要考虑 转义
var reg = /<%=\s*([^%>]+\S)\s*%>/;
// 返回的是一个对象(数组)
var match = null;
// 使用 while循环 进行检查,知道没有匹配的内容
while (match = reg.exec(str)){
// 匹配到的字符串
var mathString = match[0]
// 子表达式匹配到的字符串
var subString = match[1];
// 打印文本内容
console.log("循环中:"+str);
// 替换字符串的内容
str = str.replace(mathString,data[subString]);
}
console.log("循环完毕:"+str);
-
演示结果为:
循环中:大家好,我叫<%= name %>,我今年<%= age %>,我的爱好为:<%= skill %>
循环中:大家好,我叫jiang,我今年<%= age %>,我的爱好为:<%= skill %>
循环中:大家好,我叫jiang,我今年10,我的爱好为:<%= skill %>
循环完毕:大家好,我叫jiang,我今年10,我的爱好为:打篮球 -
常见的模板插件:
-
BaiduTemplate(百度开发):http://tangram.baidu.com/BaiduTemplate/
-
ArtTemplate(腾讯开发):https://github.com/aui/artTemplate
-
velocity.js(淘宝开发):https://github.com/shepherdwind/velocity.js/
-
Handlebars:http://handlebarsjs.com/
ArtTemplate基本使用
- 模板引擎的用法大同小异,
ArtTemplate
由于性能优秀,这里我们演示ArtTemplate的用法: - 导入模板引擎:将下载好的ArtTemplate导入到页面中:
<script type="text/javascript" src = "./files/template-native.js"></script>
- 定义模板:
<% %>
:这样的语法是定义逻辑表达式;
<%=内容 %>
:这样的语法为输出表达式;
注意:这里的模板type='text'
如果写成javascript
会执行:
<script type="text" id = "templ01">
<ul>
<li><%=name %></li>
<li><%=age %></li>
<li><%=skill %></li>
<li>
<ul>favouriteFood
<% for(var i = 0 ;i < favouriteFood.length;i++) {%>
<li><%=favouriteFood[i] %></li>
<% } %>
</ul>
</li>
</ul>
</script>
- 定义对象;
- 调用模板引擎的方法,传入对象,我们可以使用
template(模板id,数据)
;
// 调用模板引擎的方法
var backHtml = template("templ01",data);
// 返回值就是填充好的内容
-
总结:
1.导入模板对象;
2.定义模板;一般情况下,模板使用中,type必须写,写成非javascript的内容,若果留空,会默认解析成为js,会报错。
3.定义对象;
4.调用模板引擎的方法,传入对象;
注意点:
一、如果出现template error错误,一般模板出错,去查找模板:1.for循环写了开头,没有写结尾;2.for循环中的分隔符写成了逗号。
二、只能接受对象,不能接受数组。 -
示例:
<body>
<script src="template-native.js"></script>
<script type="text" id="temp">
<% for(var i=0; i<people.length; i++){ %>
<ul>
<li><%= people[i].name %></li>
<li><%= people[i].skill %></li>
</ul>
<% } %>
</script>
<script>
var data = {
people:[
{name: "baby", skill: "演戏"},
{name: "yijiang", skill: "负责帅"},
{name: "mage", skill: "负责美"}
]
};
var backHtml = template("temp",data);
document.write(backHtml);
</script>
</body>
使用演示:luowang
同源以及跨域
同源
- 同源策略是浏览器的一种安全策略,所谓同源是指
域名
,协议
,端口
完全相同。
URL | 说明 | 是否允许通信 |
---|---|---|
http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 允许 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不同文件夹 | 允许 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不同端口 | 不允许 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不同协议 | 不允许 |
http://www.a.com/a.js http://70.32.92.74/b.js |
域名和域名对应ip | 不允许 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不同 | 不允许 |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
http://www.cnblogs.com/a.js http://www.a.com/b.js |
不同域名 | 不允许 |
跨域方案
-
顶级域名相同的可以通过domain.name来解决,即同时设置 domain.name = 顶级域名(如example.com);
-
document.domain + iframe
-
window.name + iframe
-
location.hash + iframe
-
window.postMessage()
-
浏览器中跨域请求方案:http://rickgray.me/2015/09/03/solutions-to-cross-domain-in-browser.html
JSONP
-
JSON with Padding
其本质是利用了html标签的src属性
标签具有可跨域
的特性,实现跨域用的是script标签
,由服务端返回一个预先定义好的Javascript
函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成; - 使用script标签,
<script src="xxx.php"></script>
,默认会发送一个get请求到对应的php页面; - 只能以GET方式请求
- 注意只能够通过get方法;
- 服务端代码:
<?php
// echo "alert('天气不错哦')";
$callBack = $_GET['callback'];
$arr = array(
'name' =>'大帅比' ,
'color' =>'red'
);
echo $callBack."(".json_encode($arr).")";
?>
- 前端代码:注意,域名不同
- 核心是通过
script标签
的src属性
提交get请求
- 核心是通过
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function fn(data){
console.log(data);
}
</script>
<script type="text/javascript" src='http://www.section02.com/seciton02_jsonP.php?callback=fn'></script>
</head>
<body>
<h1>区域1的页面_jsonP演示</h1>
</body>
</html>
- 如果我们定义的fn方法有形参,会将从服务器拿到的括号中的值传递给形参,并且如果传递过来的是json字符串,会自动帮我们转化为js对象。
jq已经帮我们封装好了jsonp的请求,直接使用即可:
- dataType预期服务器返回的数据类型为jsonp;
- "jsonp": JSONP 格式。使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数;
- 如果需要给jsonp指定回调函数:通过jsonpCallback为jsonp请求指定一个回调函数名。这个值将用来取代jQuery自动生成的随机函数名。这主要用来让jQuery生成度独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存GET请求的时候,指定这个回调函数名。
<script>
function eatFood() {
console.log("好好吃哟");
}
</script>
<script src="../03-jq-ajax/jquery.min.js"></script>
<script >
$.ajax({
url:"01-jsonp-script.php",
dataType:"jsonp",
callback:eatFood()
})
</script>
jQuery 的$.ajax()
-
方法当中集成了JSONP的实现,可以非常方便的实现跨域数据的访问。
-
dataType: 'jsonp'
设置dataType值为jsonp即开启跨域
访问; -
jsonp
可以指定服务端接收的参数的“key”值,默认为callback; -
jsonpCallback
可以指定相应的回调函数,默认自动生成 -
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript" src='jquery/jquery-3.0.0.min.js'></script>
</head>
<body>
<h1>区域1的页面</h1>
<input type="button" name="" onclick='sendAjax()' value="jquery区域请求">
</body>
</html>
<script type="text/javascript">
function sendAjax(){
$.ajax({
url:'http://www.section02.com/sectcion02_jqJsonp.php',
type:'post',
dataType: 'jsonp',
data:{name:'itt'},
success:function(data){
console.log(data);
}
})
}
</script>
天气预报
-
一些平台为我们提供了可以直接使用的接口,我们只需要按照他们提供的格式提交数据即可。
-
开发者秘钥ak:0A5bc3c4fb543c8f9bc54b77bc155724
瀑布流
什么是瀑布流?
-
瀑布值得是从上往下流动的水,并且水量也较大,瀑布流指的是内容、信息,像瀑布一样从上往下进行排布。
-
瀑布流:示例取自:堆糖网:http://www.duitang.com/topics/
瀑布流实现原理
-
瀑布流的核心为:
-
宽度
一致,高度
参差不齐; -
新增行的内容,优先添加到
最矮
的下方。 -
难点:
-
当我们到了新一行时,如何获取上一行高度最小的行高?
-
可以定义数组用来保存高度,新增了以后替换数组中原始的高度即可。
-
实现技术:
-
Ajax;
-
jq->Ajax请求;
-
模板引擎->渲染页面。
-
知识点:
-
模板引擎;
-
jqajax请求;
-
php中,字符串和php对象的相互转化;
-
jq插件写法:瀑布流的算法。
-
补充:
-
可以直接使用jq对象点出来的语法,除了jq本身,还有jq的插件,这里我们将瀑布流封装成jq插件。
-
jq插件:
-
$.fn.extend
,调用:$('xxx').fun;
; -
$.extend
,调用:$.fun;
; - 注:这里的fun跟我们定义的时候写的属性名一致;
- jq插件命名一般建议使用
jQuery.插件名.js
格式; - 插件中的方法名建议和插件名一致。
-
// 为 jq 添加 插件
// 注册完毕以后 使用 $("xxx").fun 使用
$.fn.extend({
study:function () {
console.log('我要好好学习了哟');
// 在这个方法中 我们可以使用 $('选择器')获取到jq对象
// this 就是我们获取到的jq对象
// 注意:容易搞混 jq对象跟dom对象 所以这里建议使用以$开头的this替代
// 一看到 $_开头的,就知道是jq对象,防止跟dom对象弄混
var $_this = this;
$_this.css({backgroundColor:'yellow'});
// jq有一个特点是 链式编程
// 为了能够链式编程 建议 return 当前使用的jq对象
return $_this;
}
});
// 注册完毕以后 使用$.fun 使用
$.extend({
play:function(){
console.log('我要玩游戏了哟');
}
})
案例:(百度开发平台)
- 1.天气展示;
- 2.近期电影展示。