Ajax:异步的javascript和xml
Ajax 的核心是XMLHttpRequest对象,该对象为向服务器发送请求和解析服务器响应提供了流畅的接口。能够以异步方式从服务器取得更多信息,用户不需要刷新页面也能取得数据。
同步和异步
同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
(简单点说:同步就是只能一件一件事的来做,而异步就是可以多件事同时进行)
一、创建ajax过程
(1)创建一个XMLHttpRequest对象
代码:
function createXhr(){
if(typeof XMLHttpRequest !="undefined"){//主流浏览器(firefox、chrome、safari、opera、IE7以上)
return new XMLHttpRequest();
}else if(typeof ActiveXObject !="undefined"){//IE浏览器创建
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
var xhr=createXhr();
<span style="white-space:pre"> </span>var xhr = null;
//这里如果直接写XMLHttpRequest,如果浏览器不支持XMLHttpRequest,则会报错
//window.XMLHttpRequest这样写,是将XMLHttpRequest当做window对象的属性来检查
//如果不存在会返回undefined,不会出错
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
(2)使用XMLHttpRequest对象的open方法创建一个新的HTTP请求
open方法接收三个参数:要发送请求的类型(get或者post)、请求的url、表示是否异步发送请求的布尔值
false表示同步请求,true表示异步请求
open方法并不会真正发送请求,而只是启动一个请求以备发送
(3)设置响应HTTP请求状态变化的函数.
onreadystatechange()函数
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300||xhr.status==304){
console.log(xhr.responseText);
}else{
console.log("请求失败:"+xhr.status);
}
}
}
(4)发送HTTP请求.
send方法,该方法接收一个参数,及要作为请求主体发送的数据
调用send方法之后,请求就会被分派到服务器
(5)获取异步调用返回的数据.
(6)使用JavaScript和DOM实现局部刷新.
二、get请求
function createXHR(){//创建Ajax对象
if(window.XMLHttpRequest){
return new XMLHttpRequest();
}else{
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
var xhr=createXHR();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText);
}else{
console.log("请求失败:"+xhr.status);
}
}
};
xhr.open('get',"example.txt",true);//true表示发送异步请求
xhr.send(null);
三、post请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script type="text/javascript">
function checkname(){
//ajax方式用户名校验
//1、获取用户名信息
var nm=document.getElementById("username").value;
//对传递的特殊字符串进行编码处理 tn&age=34
//同时对中文也会进行编码处理
nm=encodeURIComponent(nm);
//把用户名信息变为“请求字符串“
var info="name="+nm+"&age=23";
//2、ajax校验
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
alert(xhr.responseText);
}
}
xhr.open('post','./05.php?addr=beijing');
//post方式传递数据是模拟form表单传递数据
//form表单的post格式数据是通过xml形式传递给服务器的
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
xhr.send(info);
}
</script>
</head>
<body>
<h2>ajax用户名的校验(post方式)</h2>
<p>用户名:<input type="text" id="username" οnblur="checkname()"></p>
<p>手机号码:<input type="text" id="usertel"></p>
</body>
</html>
四、GET和POST的区别,何时使用POST?
get和post方式区别:
1. GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给服务器。在Ajax请求中,这种区别对用户是不可见的。
2.GET方式对传输的数据大小有限制(通常不能大于2KB),而使用POST方式传递的数据量要比GET方式大的多(理论上不受限制)
3.GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全性问题,而POST方式相对来说就比较安全。
4.GET方式和POST方式传递的数据在服务器端的获取也不相同。在PHP中,GET方式的数据可以用$_GET[]获取,POST使用$_POST[]获取。两种方式都可以使用$_REQUEST[]来获取。
GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符 POST:一般用于修改服务器上的资源,对所发送的信息没有限制。 GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。
然而,在以下情况中,请使用 POST 请求: 无法使用缓存文件(更新服务器上的文件或数据库) 向服务器发送大量数据(POST 没有数据量限制) 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
get请求需要注意的地方:
1.缓存(将请求地址缓存起来,如果下一次请求地址不变,则下次请求的内容将读取缓存中的数据,而不会去请求服务器上的数据)
我们可以通过在url?后面连接一个随机数或者时间戳来解决这一问题
2.传递中文参数乱码问题,通过编码encodeURI来解决
<body>
<input type="button" name="" value="提交数据" id="btn">
<script type="text/javascript">
var oBtn = document.getElementById("btn");
oBtn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.open('get','get_form.php?username='+encodeURI('李四')+'&age=123&'+new Date().getTime(),true);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
alert(xhr.responseText);
}
}
}
}
</script>
</body>
get_form.php
<?php
header("content-type:text/html;charset=utf-8");
$username = $_GET['username'];
$age = $_GET['age'];
echo "欢迎哈哈哈,你的名字是:{$username},年龄是:{$age}";
?>
post请求需要注意的地方:
1.post方式,数据放在send()里面作为参数传递
2.需要声明要发送的数据的类型
<body>
<input type="button" name="" value="提交数据" id="btn">
<script type="text/javascript">
var oBtn = document.getElementById("btn");
oBtn.onclick = function(){
var xhr = new XMLHttpRequest();
xhr.open('post','post_form.php',true);
//post方式,数据放在send()里面作为参数传递
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');//声明发送的数据类型
xhr.send('username=李四&age=300');
//post方式没有缓存问题和编码问题
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
alert(xhr.responseText);
}
}
}
}
</script>
</body>
post_form.php
<?php
header("content-type:text/html;charset=utf-8");
$username = $_POST['username'];
$age = $_POST['age'];
echo "你的名字是:{$username},年龄是:{$age}";
?>
五、XMLHttpRequest
对象
它的属性有:
onreadystatechange 每次状态改变所触发事件的事件处理程序。
responseText 作为响应主体被返回的文本。
responseXML 将响应信息格式化为Xml Document对象并返回
status 响应的HTTP状态,比如常见的404(未找到)和200(已成功)
status Text HTTP状态说明
当XHR对象把一个HTTP请求发送到服务器的过程中会经历几个状态,直到请求被处理,然后才接收一个回应。readyState
就是XHR请求的状态属性,它本身有5个属性值:
0:未初始化。尚未调用open()方法
1:启动。已经调用open()方法,但尚未调用send()方法
2:发送。已经调用send()方法,但尚未接收到响应
3:接收。已经接收到部分响应数据 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了
只要readyState属性的值由一个值变成另一个值,都会触发一次onreadystatechange事件。通常,我们只对readyState值为4的阶段感兴趣,因为这时所有数据都已经就绪。
不过,必须要在调用open()方法之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性
六、http状态码
1字头:消息。这一类型的状态码,代表请求已被接受,需要继续处理。
2字头:成功。这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
3字头:重定向。这类状态码代表需要客户端采取进一步的操作才能完成请求。
4字头:客户端错误。这类状态码代表了客户端看起来可能发生错误,妨碍了服务器的处理。
5字头:服务器错误。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生
100 Continue
初始的请求已经接受,客户应当继续发送请求的其余部分
101 Switching Protocols
服务器将遵从客户的请求转换到另外一种协议
201 Created
服务器已经创建了文档,Location头给出了它的URL。
202 Accepted
已经接受请求,但处理尚未完成。
203 Non-Authoritative Information
文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝
204 No Content
没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的
205 Reset Content
没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容
206 Partial Content
客户发送了一个带有Range头的GET请求,服务器完成了它
300 Multiple Choices
客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在Location应答头指明。
301 Moved Permanently
客户请求的文档在其他地方,新的URL在Location头中给出,浏览器应该自动地访问新的URL。
302 Found
类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。
303 See Other
类似于301/302,不同之处在于,如果原来的请求是POST,Location头指定的重定向目标文档应该通过GET提取
305 Use Proxy
客户请求的文档应该通过Location头所指明的代理服务器提取
307 Temporary Redirect
和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是 POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码: 当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。
400 Bad Request
请求出现语法错误。
401 Unauthorized
客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。
403 Forbidden
资源不可用。
405 Method Not Allowed
请求方法(GET、POST、HEAD、Delete、PUT、TRACE等)对指定的资源不适用。
406 Not Acceptable
指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容
407 Proxy Authentication Required
类似于401,表示客户必须先经过代理服务器的授权。
408 Request Timeout
在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。
409 Conflict
通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。
410 Gone
所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。
411 Length Required
服务器不能处理请求,除非客户发送一个Content-Length头。
412 Precondition Failed
请求头中指定的一些前提条件失败
413 Request Entity Too Large
目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头
414 Request URI Too Long
URI太长
416 Requested Range Not Satisfiable
服务器不能满足客户在请求中指定的Range头
501 Not Implemented
服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求
502 Bad Gateway
服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答
503 Service Unavailable
服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头
504 Gateway Timeout
由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答
505 HTTP Version Not Supported
服务器不支持请求中所指明的HTTP版本
七、HTTP头部信息
Accept 表示浏览器能够处理的内容类型
Accept-Encoding 表示浏览器能够处理的压缩编码
Accept-Language 表示浏览器当前设置的语言
Host 表示发出请求的页面所在的域
Referer 表示发出请求页面的URI
User-Agent 表示浏览器的用户代理字符串
Connection Keep-Alive 浏览器与服务器之间连接的类型
八、传统Ajax问题
1、可以无刷新改变页面内容,但无法改变页面URL2、为了更好的可访问性,内容发生改变后,通常改变URL的hash
3、hash的方式不能很好的处理浏览器的前进、后退等问题,进而浏览器引入了onhashchange的接口,不支持的浏览器只能定时去判断hash是否改变。但这种方式对搜索引擎很不友好,twitter和google约定了使用#!xxx(即hash第一个字符为!),搜索引擎进行支持。
九、Ajax模拟登陆
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ajax登录</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
list-style: none;
text-decoration: none;
outline: none;
}
a{
display: inline-block;
position: absolute;
top: 10px;
right: 30px;
}
.box{
display: none;
width: 300px;
height: 300px;
position: absolute;
top:50%;
left:50%;
margin-top: -150px;
margin-left: -150px;
/*border:1px solid #ccc;*/
padding: 10px;
z-index: 9999;
background: #fff;
}
.list{
margin-top: 15px;
}
.list label{
display: inline-block;
text-align: right;
/*border: 1px solid red;*/
width: 80px;
}
.input_list{
display: inline-block;
margin-left: 10px;
}
.input_list .sub{
padding: 5px;
width: 80px;
cursor: pointer;
}
.mask{
display: none;
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,.5);
z-index: 999;
}
</style>
</head>
<body>
<a href="javascript:;" id="link">登录</a>
<div class="box">
<form action="#">
<div class="list">
<label>姓名:</label>
<div class="input_list">
<input type="text" name="username" id="username" placeholder="请输入你的姓名">
</div>
</div>
<div class="list">
<label>密码:</label>
<div class="input_list">
<input type="password" name="pwd" id="pwd" placeholder="请输入你的密码">
</div>
</div>
<div class="list">
<label>家庭住址:</label>
<div class="input_list">
<input type="text" name="address" id="address" placeholder="请输入你的住址">
</div>
</div>
<div class="list">
<label></label>
<div class="input_list">
<input type="button" class="sub" value="提交" id="subBtn">
</div>
</div>
</form>
</div>
<div class="mask"></div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(function(){
$("#link").click(function(){
$(".box").show();
$(".mask").show();
});
$("#subBtn").click(function(){
var url = "http://localhost/mywork/ajax_login/test.php";
var obj = {
username : $("#username").val(),
password : $("#pwd").val()
};
// console.log(obj);
$(".box").hide();
$(".mask").hide();
$.post(url,obj,function(data){
if(data == "yes"){
alert("登录成功");
$("#link").html("欢迎 "+$('#username').val()+" 登陆");
}else{
alert("登录失败");
}
});
});
});
</script>
</body>
</html>
test.php
<?php
$username=$_POST['username'];
$password=$_POST['password'];
if($username == 'admin' && $password == '123'){
echo "yes";
}else{
echo "no";
}
?>