AJAX
准备工作-服务器环境的搭建
ajax可以在本地使用,但是牵扯到不同源问题,需要跨域操作。下面是两个文件的代码,test.html放在桌面上,cors.php放在搭好的服务器上面,我这里配置的端口号是9096,端口号可以自行配置,默认的话是80端口,双击打开test.html文件,控制台会输出下面信息
{"code":200,"msg":"success"}
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script>
$.get("http://localhost:9096/testCode/cors/cors.php").done(function(data){
console.log(data)
})
</script>
</body>
</html>
cors.php
<?php
header("access-control-allow-origin: *");
$result = array(
'code' => 200,
'msg' => 'success'
);
if($_GET['callback'])
echo ';'. $_GET['callback'] . '(' . json_encode($result) .')';
else
echo json_encode($result);
?>
对上面这些不懂得可以直接忽略,不影响下面学习,学习ajax最好在本地配置一个服务器,将代码放在服务器下面对应的文件夹中通过127.0.0.1或者localhost或者配置虚拟主机来访问。
最简单的办法是在网上下载一个集成的环境,我们以php语言和apache服务为例,比如集成环境phpstudy、wamp等,爱鼓捣的码友可以自己动手一步一步的配置。我本地使用的是phpstudy集成环境,安装使用都比较方便,也不大才35.6M。
温馨提示:看到这里的默认已经在本地搭建好服务器,并将端口号配置为9096,如果没有配置端口号将下面的9096替换为80或者省去即可。下面的代码均放在服务器下面通过127.0.0.1或者localhost或者配置虚拟主机来访问。
什么是Ajax
全称 Asynchronous JavaScript and XML (异步JavaScript和XML)
用JavaScript异步的形式去操作xml,它要完成的工作也就是数据交互。
数据交互也就是可以从某个地方拿取数据,也可以发送数据到某个地方。
一般情况下我们会使用ajax和后端(php、nodejs等)进行数据交互,我们会把数据发送给后端,后端接收到数据后做出一些操作后返回一些数据给我们,这就是数据交互,ajax做的就是这一块。
它有一个特点,就是体现在异步交互上面,可以节约用户时间,提高用户体验,减少数据请求等。
ajax可以在不刷新页面的情况下发送一个请求到某个地方获取一些数据。
例子:这里以一个静态文件作为例子,test.html与1.txt在同一级,都在服务器下面的www目录下,我们打开浏览器,访问localhost:9096/test.html,单击按钮将会请求同一目录下1.txt文件的内容,如果成功的话会弹出一个弹出框显示hello,ajax!。
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
//ajax的整个流程可以理解为浏览器操作,比如:
var xhr = new XMLHttpRequest();//可以想象为打开浏览器
xhr.open('get','1.txt',true);//在地址栏输入地址
xhr.send();//按下回车提交
//等待浏览器返回内容
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {//返回内容
if(xhr.status == 200){//200成功状态码
alert(xhr.responseText);
}else{
alert('出错了,Err:' + xhr.status );
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn">
</body>
</html>
1.txt
hello,ajax!
创建Ajax对象
- 创建一个ajax对象,上面的new XMLHttpRequest()适用通用浏览器,ie6以下是new ActiceXObject(‘Microsoft.XMLHttp’),对此我们需要解决兼容性问题。
//方法一:
var xhr = null;
if(window.XMLHttpRequest{
xhr = new XMLHttpRequest();
}else{
xhr = new ActiceXObject('Microsoft.XMLHTTP');
}
//方法二:
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
数据的请求
open方法有三个参数
打开方式,也就是请求方式(get、post等,其他的可以在网上找一下)
- get
- 把数据名称和数据值用等号(=)连接,如果有多个的话,那么它会把多个数据组合用&进行连接,然后把数据放到url?后面传到指定页面
- url长度限制的原因,我们不要通过get方式传递过多的数据
- post
- 理论上无限制,实际上我们可以通过改变php.ini配置文件中的post_max_size来限制传送数据的大小
- get
请求地址
- 数据提交的地址,默认是当前页面
是否异步
- 异步:非阻塞,前面的代码不会影响后面代码的执行
- 同步:阻塞,前面的代码会影响后面代码的执行
setRequestHeader方法
- xhr.setRequestHeader(‘content-type’,’application/x-www-form-urlencoded’);//申明发送的数据类型
send方法
- get请求的send方法无需参数,例如:xhr.send();get请求的数据放在url中,例如
xhr.open('get','get.php?username=zhou&age=21',true);
- post请求的数据放在send方法里面,例如:
xhr.send('username=zhou&age=21');
数据的获取
onreadystatechange事件: (on readystate change)当readyState改变的时候触发
readyState : ajax工作状态
- 0 (未初始化)对象已经创建,但还没有调用open()方法
- 1 (启动)已经调用open() 方法,但尚未调用send()方法发送请求
- 2 (发送)send()方法已调用,请求已经发送完成,但尚未接收到响应
- 3 (接收)已经接收到部分响应数据
- 4 (完成)已经接收到了全部数据,而且已经可以在客户端使用了
status : 服务器状态,http状态码
responseText : ajax请求返回的内容就被存放到这个属性下面
下面是一个例子,text.html和get.php在服务器下同一级
下面用到了PHP中的json_encode函数,和JS中的JSON.parse()方法,意义在于将这些数据统一转换为json格式。
text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
//创建对象
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('get','get.php',true);
xhr.send();//发送请求
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){//成功
alert(JSON.parse(xhr.responseText));
}else{
alert('出错了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn">
</body>
</html>
get.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);// 关闭错误报告
$arr = array('zhou','21','男');
echo json_encode($arr);
get请求
get请求有时可能会有缓存和乱码问题,在下面有相应解决方案
例子:
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('get','get.php?username=zhou&age=21',true);
xhr.send();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){
alert(JSON.parse(xhr.responseText));
}else{
alert('出错了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn">
</body>
</html>
get.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$username = $_GET['username'];
$age = $_GET['age'];
echo json_encode("$username,$age");
get请求的响应默认是可以缓存的(响应应该包含一个到期时间, 或者有一个验证器),get请求被缓存,导致页面数据没有刷新,我们有时候需要针对缓存问题有一个解决方案:
- 缓存问题,在url?后面链接一个随机数,这里使用时间戳
xhr.open('get','get.php?username=zhou&age=21&'+new Date().getTime(),true);
- 乱码问题,使用encodeURI对数据进行编码
xhr.open('get','get.php?username='+encodeURI('周')+'&age=21&'+new Date().getTime(),true);
post请求
- post必须要告诉后端发送的数据是什么类型的,然后后端才能按照这个类型来解析数据,如果不告诉后端发送的是什么类型,后端将不解析。
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');//post必须要告诉后端发送的数据是什么类型的
- post方式,数据放在send()里面作为参数传递
xhr.send('username=zhou&age=21');
- post和get不一样,post没有缓存问题,post用来提交数据,是没有缓存的,get一般用来的到数据,可能存在缓存问题。这跟ajax没有关系,跟web机制有关系。
- post没有乱码问题,因为在发送数据的时候已经声明了发送的数据是什么类型的,所以在发送数据的时候自动帮你把数据进行编码,比如下面这个,在发送数据的时候自动对数据进行url编码,所以说无需在对数据进行编码。
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
post请求的例子:
text.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var oBtn = document.getElementById('btn');
oBtn.onclick = function(){
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(e){
xhr = new ActiceXObject('Microsoft.XMLHttp');
}
xhr.open('post','post.php',true);
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');//post必须要告诉后端发送的数据是什么类型的
xhr.send('username=zhou&age=21');
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if(xhr.status == 200){
alert(JSON.parse(xhr.responseText));
}else{
alert('出错了,Err:'+xhr.status);
}
}
}
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn">
</body>
</html>
post.php
<?php
header('content-type:text/html;charset="utf-8"');
error_reporting(0);
$username = $_POST['username'];
$age = $_POST['age'];
echo json_encode("$username,$age");