目录
Ajax应用
前言
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
- Ajax = 异步 JavaScript 和 XML 或者是 HTML(标准通用标记语言的子集)。
- Ajax 是一种用于创建快速动态网页的技术。
- Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。
介绍
在学习Ajax之前,我们先来聊一下同步和异步的问题。
什么是同步?什么是异步呢?
首先来说同步,同步相对来说更好理解一点。比如调用一个方法,这个方法没有调用完成之前,后续的代码将不能够执行。这就是同步。
那么什么是异步呢,异步调用有些类似于消息传递,一旦开始,方法调用就会立刻返回,调用者就可以继续后面的操作。需要知道的是,此时,异步方法通常会在另外一个
线程中真实
的执行着。整个过程当中,并不会阻碍调用者的工作。
而Ajax主要的工作就是通过异步来帮助我们传输数据。
基本使用
下面我们通过完成一个基本的功能来看一下ajax的写法:
需求:点击按钮,弹出01.txt当中的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">点击</button>
</body>
</html>
<script>
window.onload = function (){
let oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var xhr = new XMLHttpRequest();
// 输入地址
xhr.open('get','01.txt',true);
// 提交
xhr.send();
// 等待服务器返回内容
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
alert(xhr.responseText);
}
};
};
};
</script>
上面的代码中,我们通过ajax技术实现了点击按钮,弹出01.txt当中内容。
整体的实现步骤如下:
- 获取元素绑定事件
- 实例化XMLHttpRequest()对象
- 调用open()方法读取指定文件
- 发送请求
- 绑定readystatechange事件,设置事件处理函数。
下面我们就来逐一的将上面的代码进行拆解讲解。
对象兼容
我们如果想在网页当中使用ajax
技术,那么首先就需要创建一个XMLHttpRequest
对象。这个对象目前的兼容情况是IE6以上以及其他的主流
浏览器都支持,但是如果想要在IE6及以下使用Ajax,我们就需要做一个兼容处理。
在IE6当中,需要使用ActiveXObject这个插件,并且要传入参数"Microsoft.XMLHTTP"。
示例代码:
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
除了使用这个if和else判断以外,还可以使用try..catch的方法来实现兼容处理。
var xhr;
try{
xhr = new XMLHttpRequest();
}catch(e) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
在上面代码中,如果宿主环境中不支持XMLHttpRequest
对象,就会出现错误从而会被catch所捕捉到,执行catch代码块中的另外一种声明方式。
表单当中的get方法和post方法
下面我们会说到ajax
的open
方法,但是在说到这个方法之前,先来了解一下form表单当中的一些内容。
例如:
<form action="1.get.php" method="get" enctype="application/x-www-form-urlencoded">
<input type="text" name="username">
<input type="submit" value="提交">
</form>
在上面的表单当中,form
标签存在几个属性,
- action 表示数据提交位置 ,默认提交到当前页面
- method 数据提交使用的方法 默认是get
- enctype 表单数据提交的格式 默认值 application/x-www-form-urlencoded
get方法和post方法
在form表单当中,提交数据有get和post两种方法,如果从本质上来说,二者其实差异不大,但是外在的表现还是存在一定的差异。
下面就来说一下这些差异,这些差异性是w3c给出的说法:
- GET在浏览器回退时是无害的(因为读取缓存),而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
关于get和post的区别,请关注另外一篇文章get 和 post区别介绍。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="1.get.php" method="get">
<input type="text" name="username">
<input type="submit" value="提交">
</form>
</body>
</html>
php代码如下:
<?php
header("Content-type:text/html;Charset=utf-8");
// 获取用户名
$username = $_GET['username'];
echo $username;
?>
在上面的案例当中,表单通过get方式向php传递了数据,在页面的地址栏位置,我们可以发现通过url地址进行提交时,
把数据名称和数据值使用=进行连接,如果是多个的话,那么会把多个数据使用&进行连接,然后把数据放到url?后面传到指定页面。
open()方法
下面我们来说一下open()方法,通过这个方法,我们可以设置发送请求的方法,地址,以及是否异步。
xhr.open(method,url,async);
例如:
xhr.open('get','01.txt',true);
当传输数据的方法为get方法的时候
我们在上面说到,传输数据的时候,如果是get方法,那么在url地址中可能存在参数,参数是以?和& 进行拼接。
例如:
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 将参数通过?的形式进行拼接
xhr.open('get','08.php?name=zhangsan&age=14',true);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
alert(xhr.responseText);
}
};
当传输数据的方法为post方法的时候
当传输数据为post方法的时候,需要传递的参数应该通过send()方法进行传递。同时需要设置一下数据传输格式。
如下:
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
例如将上面的案例转换成post方法,代码如下:
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('post','08.php',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("name=zhangsan&age=14");
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
alert(xhr.responseText);
}
};
绑定onreadystatechange事件
上面我们将数据发送到了服务器,服务器接收到后会进行一定的处理,而onreadystatechange事件监听的就是XMLHttpRequest对象的readyState的状态。
一旦状态发生改变都会触发这个事件。
xhr.onreadystatechange = function(){};
readyState和status
readyState里面存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
status里面存储的是http状态码,根据不同的情况,服务器会返回不同的状态码。200表示成功。
一般情况下,我们都是等readyState的值变为4,status的值为200的时候才去处理返回的数据。
例如:
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200){
// code ...
}
}
获取服务器响应
当我们通过XMLHttpRequest对象向服务器发起请求之后,服务器会给予我们一定的响应,那么我们该如何获取响应呢?
可以通过XMLHttpRequest 对象的 responseText(获得字符串形式的响应数据。) 或 responseXML(获得 XML 形式的响应数据) 属性。
例如:
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200){
alert(xhr.responseText);
}
}
小练习:点击按钮读取数据
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻列表</title>
</head>
<body>
<button id="btn">点击</button>
<ul id="list">
</ul>
</body>
<script>
window.onload = function(){
// 获取list
var oList = document.getElementById('list');
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open('get','06.get.php',true);
xhr.send();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200){
// 拿到数据进行处理
console.log(xhr.responseText);
var news = JSON.parse(xhr.responseText);
console.log(news);// 数组
var html = '';
for(let i=0;i<news.length;i++){
// 将数据插入到li 并且存储到html
html += `<li><a href="">${news[i].title}</a> [<span>${news[i].date}</span>]</li>`;
}
oList.innerHTML = html;
}
};
};
};
</script>
</html>
php代码:
<?php
header("Content-type:text/html;Charset=utf-8");
$arr_news = [
['title'=>'美国从不愿提及的真相:中朝战俘境遇','date'=>'2019-05-27'],
['title'=>'县级领导网上筹款20万治病 家人及官方回应','date'=>'2019-05-26'],
['title'=>'杜特尔特“拷问”女副总统为啥不笑 13分钟后见效','date'=>'2019-05-25'],
['title'=>'翟天临又上热搜了 是被半夜改论文毕业生骂上去的','date'=>'2019-05-24'],
['title'=>'美国百岁老人被房东驱逐 惊动了“硬汉”施瓦辛格','date'=>'2019-05-23'],
['title'=>'实习女律师当街遇害 知情者:行凶男子想杀漂亮女孩','date'=>'2019-05-22'],
['title'=>'国内成品油价格迎来年内第八涨 加满一箱油多花2元','date'=>'2019-05-21'],
['title'=>'中安民生“以房养老”骗局:老人被逼卖房还高利贷','date'=>'2019-05-20'],
['title'=>'任正非:华为必须做世界第一 若第二可能活不下来','date'=>'2019-05-19'],
['title'=>'91岁李兆基退休:香港富豪“四大天王”时代落幕','date'=>'2019-05-18']
];
echo json_encode($arr_news);
上面的代码中,我们点击按钮就可以在页面中显示php给我们返回的数据。
ajax函数封装
为了便于操作,我们也可以将ajax常用的操作进行封装。
function ajax(method, url, data, success) {
var xhr = null;
try {
xhr = new XMLHttpRequest();
} catch (e) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
if (method == 'get' && data) {
url += '?' + data;
}
xhr.open(method,url,true);
if (method == 'get') {
xhr.send();
} else {
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
xhr.onreadystatechange = function() {
if ( xhr.readyState == 4 ) {
if ( xhr.status == 200 ) {
success && success(xhr.responseText);
} else {
alert('出错了,Err:' + xhr.status);
}
}
}
}
有了这个函数,上面的小练习就可以写成下面的样式:
ajax('get','06.get.php','',function(data) {
var data = JSON.parse( data );
var oUl = document.getElementById('ul1');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>';
}
oUl.innerHTML = html;
});
我们也可以通过轮询的形式让前端新闻自动请求后端的数据:
setInterval(function() {
ajax('get','getNews.php','',function(data) {
var data = JSON.parse( data );
var oUl = document.getElementById('ul1');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li><a href="">'+data[i].title+'</a> [<span>'+data[i].date+'</span>]</li>';
}
oUl.innerHTML = html;
});
}, 3000);
小练习
下面通过ajax + 多列布局来实现瀑布流效果:
html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin:0;
padding:0;
box-sizing: border-box;
}
body{
background:#352323 url(images/a.png);
}
img{
display:block;
}
section{
max-width:95%;
margin:0 auto;
overflow:hidden;
column-count: 5;
column-gap:0;
column-fill: auto;
}
figure{
border:2px solid pink;
margin:0 5px 10px;
break-inside: avoid;
padding:5px;
}
figure img{
width:100%;
}
figcaption{
padding:10px 0;
text-align:center;
font-weight:900;
color:#a77869;
}
</style>
</head>
<body>
<section>
<!-- <figure>
<img src="images/1.jpg" alt="">
<figcaption>往后余生,风雪是你</figcaption>
</figure> -->
</section>
</body>
<script src="ajax.js"></script>
<script>
let section = document.getElementsByTagName('section')[0];
ajax('get','img.php','num=100',function(data){
let img_data = JSON.parse(data);
console.log(img_data)
for(let i=0;i<img_data.length;i++){
// 创建figure标签
let figure = document.createElement('figure');
// 创建里面的两个子元素
let img = document.createElement('img');
img.src = img_data[i];
let figcaption = document.createElement('figcaption');
figcaption.innerHTML = "往后余生,风雪是你";
figure.appendChild(img);
figure.appendChild(figcaption);
section.appendChild(figure)
}
})
</script>
</html>
php代码如下:
<?php
header("Content-type:text/html;Charset=utf-8");
$num = $_GET['num'];// 通过get方式传递数据
$img = file("img.txt"); // 读取文件地址
$arr_url = array();
for($i=0;$i<$num;$i++){
$url = array_rand($img);
array_push($arr_url,$img[$url]);
}
// 返回json数据
$a = json_encode($arr_url,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
echo $a;
在上面的代码中,我们只需要每次在请求的时候设置好num参数即可以得到图片。