原生ajax
关于什么是ajax上一篇文章中已简单介绍,在此再次对ajax进行详细介绍,已帮助刚入坑前端的学子了解ajax,揭开ajax的神秘面纱。许多刚接触ajax的朋友会觉得ajax十分神秘、不可思议、难以理解。ajax是啥?能用来做什么?ajax都包含哪些内容?ajax的工作原理是什么?ajax是如何和后端进行交互的?又是怎样接收处理后端返回的数据......其实ajax并不难,或则说ajax本身并不难。个人认为ajax的学习的难度在于:①ajax的原理,不了解原理则会产生以上所说的一些疑问,觉得不可思议。②其次难度在于数据传输的格式:xml/json,想要玩转ajax就必须熟练掌握xml和json两种常用的数据传输格式。③工作中前端和后端是分开的,因此刚学习ajax时难免产生这样的疑问:后端是怎么接收我传送过去的数据,又是怎样给我返回的?...诸如此类的问题。ajax是数据交互的桥梁,链接前后端,所以想要玩转ajax最好能稍微了解一些后端的知识 ,这样自己练习时也方便。个人推荐php(传说中最好的语言),简单方便。④ajax报错时,不容易排查寻找错误。许多初学者在练习使用时总会出现各种各样奇奇怪怪的报错,手足无措。下面就针对以上所说问题进行简单的解答,希望可以帮助到刚入坑的小伙伴们,文中若有错误还请大神包涵、指教,衷心感谢。
1:什么是ajax?
Ajax不是一门新技术,是旧技术的新应用。Ajax即: 异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。简单的来说,就是:在不重载网页的情况下与服务器进行数据交互,并将返回的数据进行有效的处理。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面,这对于用户体验十分不好。使用 AJAX 的应用程序案例:谷歌地图、腾讯微博、优酷视频、人人网等等,目前基本上所有网站都在使用ajax技术。
2:ajax可以做什么?为什么要使用ajax?
上面对ajax的定义、介绍其实已经回答了这个问题。ajax的功能就是实现:页面和web服务器之间数据的异步传输。关于异步和同步可以看上一篇文章,其中对异步同步进行了简单介绍。同步:不采用ajax的页面,当用户在页面发起请求时,将会刷新整个页面,刷新快慢取决于服务器的处理快慢。在这个过程中用户必须得等待,无法进行其他操作。客户端和服务器传递了许多多余的数据,效率低,等待时间长,用户体验差。异步:采用ajax技术,可以实现页面的局部更新,而不是整个页面的更新,当用户发起请求后,用户还可以进行页面上的其他操作。客户端和服务端间只传递需要的数据,效率高,用户体验性较好。
3:ajax原理,图解ajax:(图引用自百度)
注册实例:下图为一个注册功能的实例图,其功能为通过ajax不刷新页面的情况下检测用户名和密码,为用户进行提示。当用户输入用户名不存在或密码错误时禁止用户发送请求并对用户进行提示。(此处不理解没关系,往下看,等会再返回来)
4:ajax具体步骤:
① 创建异步对象(XMLHttpRequest)。
② 设置请求行(请求行内参数1:请求方式get/post,参数二:设置请求url。注:get方式数据拼接在url中)。
③ 设置请求头(get方式可以省略,post方式无数据时也可省略)。
④ 回调函数,处理从服务器返回的数据。
⑤ 请求体,发送请求,post方式数据放于send()中,get方式或post无数据时为:null。
5:XMLHttpRequest兼容性问题:
XMLHttpRequest 对象:
所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
XMLHttpRequest用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
创建 XMLHttpRequest 对象
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象的语法:
variable=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
variable=new ActiveXObject("Microsoft.XMLHTTP");
为了应对所有的现代浏览器,包括 IE5 和 IE6 ,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject :var xhr;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr=new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
6:发送get请求(若不清楚get以及post可查看上一篇文章,链接在底部)
<p>请输入你的姓名:</p>
<input type="text" class="txt" placeholder="姓名:" />
<div class="btnget">get请求</div>
<div class="btnpost">post请求</div>
<div class="shujubg">
<div class="shuju">
<p>下面是发送ajax请求后返回的get数据:</p>
<span></span>
</div>
<div class="shujupost">
<p>下面是发送ajax请求后返回的post数据:</p>
<span></span>
</div></div>
js(ajax)部分代码:
//GET方式发送数据:
$(".btnget").click(function(){
//1:创建异步对象
var xhr=new XMLHttpRequest();
//2:设置请求行
xhr.open('get','./php/data.php?name='+$(".txt").val());
//3:设置请求头(get可以省略)
//4:回调函数(onreadystatechange事件)
xhr.onreadystatechange=function(){
//4.1:判断ajax返回状态,数据完全返回成功执行函数
if(xhr.readyState==4&&xhr.status==200){
$(".shuju>span").html(xhr.responseText);
$(".shuju>span").css("color","red");
}
}
//5:发送请求
xhr.send(null);
})
后端php部分代码:(接收通过ajax传送过来的数据,并将之原样返回给前端)
<?php
//设置中文编码
header('content-type:text/html;charset=utf-8');
//通过超全局get获取get方式传送来的数据:
$name=$_GET['name'];
echo $name."这是从后端返回的数据啊";
?>
运行效果图:(哼哼是通过ajax的get方式发送给后端,然后后端原样返回,前端接收后显示出来的)
注:get方式数据拼接在url后,以&符拼接。
7:发送post请求:
js(ajax)代码:
//POST方式发送数据:
$(".btnpost").click(function(){
//1:创建异步对象
var xhr=new XMLHttpRequest();
//2:设置请求行
xhr.open('post','./php/postdata.php');
//3:设置请求头(get可以省略)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
//4:回调函数(onreadystatechange事件)
xhr.onreadystatechange=function(){
//4.1:判断ajax返回状态,数据完全返回成功执行函数
if(xhr.readyState==4&&xhr.status==200){
$(".shujupost>span").html(xhr.responseText);
$(".shujupost>span").css("color","red");
}
}
//5:发送请求,get方式或则数据为空时send值为null
var data='name='+$(".txt").val();
xhr.send(data);
})
php部分代码:(功能也是原样返回,前端post方式提交后端则用$_post接收)
<?php
//设置中文编码
header('content-type:text/html;charset=utf-8');
//通过超全局get获取get方式传送来的数据:
$name=$_POST['name'];
echo $name."这是从后端返回的数据啊";
?>
注意:psot方式必须设置请求头!!!格式固定。post方式要传送的数据不跟在url后面!数据必须写在send()内!
8:get和post的选择
关于get与post的选择上一篇以详细叙述,在此再次简单说明:
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
9:async参数
open()方法中共有3个参数:
method:指定请求类型get/post,默认为get
url:文件在服务器上的位置(请求的url)
async:指定请求为异步还是同步,true(异步),false(同步),默认为true
一般很少使用第三个参数async,因为ajax本身是实现异步数据传输的,将之设置为同步,ajax便失去了本身的意义。但存在一种特殊情:例如:当我们希望某些方法在ajax完成,拿到ajax传回的数据后再执行,那么此时我们就将使用async参数,将异步转换为同步,此时程序将顺序执行,确保在拿到返回的数据后再执行后面的方法。此处只是简单举例说明,若不理解,具体可自行百度搜索其他博客查看。
10:XMLHttpRequest重要属性
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
下面是 XMLHttpRequest 对象的三个重要的属性:
属性 | 描述 |
---|---|
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
|
status | 200: "OK" 404: 未找到页面 |
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
11:ajax常见错误:
在说常见错误之前首先先说说,作为前端程序员必须熟练使用的神器:浏览器开发者工具,目前主流浏览器都提供有此功能,快捷键:F12。按下f12快捷键即可打开开发者工具,开发者工具是前端程序员使用最多最频繁的调试工具,功能强大!工具界面截图如下:
elements:显示网页所有源代码(包含html以及部分嵌入在html中的css,js),可以方便的查看网页源代码
console:控制台,调试时最常用
network(英译:网络):包含http请求,所有的数据等(调试ajax必用)
403或则出现parsererror错误:通常出现此错误,首先应该想到的就是url请求不正确,其次也可能是请求参数不合法。例如请求参数数据类型与后端接收数据类型不一致
404:最常见的错误,请求url错误,找不到文件
500系列错误:一般500系列错误问题不在前端,而在后端,出现500系列错误就不要一个人苦苦寻找错误了,而应该联系后端一起排查错误!
ajax的简单封装
1:为什么要封装,如何封装?
我们非常熟悉ajax的步骤后,便可以不必将关注重点放在ajax本身上了,而应该将更多的精力放在业务逻辑上、交互效果上,此时将ajax封装成方法就非常必要了。
封装的思路:
固定的部分抽取,不固定的部分作为参数,如果参数数量很多,可以使用对象来优化。
如何判断自己封装的好坏:
1:功能能否正常执行
2:代码的简洁度,可读性
3:考虑的问题是否足够全面,兼容性问题,异常处理等
2:get方法封装:
/**
* get方法参数:
* 1:url:ajax请求地址
* 2:data:要发送的数据(value1=key1&value2=key2...)
* 3:success:回调函数
* */
function my_get(url,data,success){
//1:创建异步对象
var xhr=new XMLHttpRequest();
//2:设置请求行(特别注意:不能忘记?)
xhr.open('get',url+"?"+data);
//3:设置请求头(get方式和post无数据时省略)
//4:回调函数
xhr.onreadystatechange=function(){
//4.1:判断请求是否成功,数据是否已返回
if(xhr.readyState==4&&xhr.status==200){
//成功时执行回调函数,将取到的数据传给用户,让用户自行处理
success(xhr.responseText);
}
}
//5:请求体,发送请求
xhr.send(null);
}
调用:
3:post方法封装:
/**
* post方法参数:
* 1:url:请求地址
* 2:data:发送数据(value1=key1&value2=key2...)
* 3:success:回调函数*/
function my_post(url,data,success){
//1:创建异步对象
var xhr=new XMLHttpRequest();
//2:设置请求行
xhr.open('post',url);
//3:设置请求头
//判断data是否有数据
if(data){
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
}else{
data=null;
}
//4:回调函数
xhr.onreadystatechange=function(){
//4.1:判断请求是否成功,数据是否已返回
if(xhr.readyState==4&&xhr.status==200){
success(xhr.responseText);
}
}
//5:请求体,发送数据
xhr.send(data);
}
调用:
以上封装的两种方法并不完美,有很大的缺陷:例如:使用者必须记住所需参数、参数的顺序。此封装方法要求所传参数顺序必须正确,若顺序错误方法也就会发生严重错误。参数越来越多时代码的书写和可读性也会很差。另外对返回的数据类型也并没有进行判断,统一返回的普通文本型。针对上述问题,进行了优化,将get/post两种方法糅合成为一个方法,将参数缩减至一个(对象型),并判断了返回数据格式,根据不同的格式返回。代码如下:
4:糅合的ajax方法:
/*ajax方法(整合get,post并将参数改为1个)
参数:有且只有一个,参数类型对象
对象属性:url(请求地址)
type(发送方式:get/post)
data(发送的数据)
success(回调函数)
* */
function my_ajax(option){
//全局变量
var url=option.url;
var data=null;
//1:创建异步对象
var xhr=new XMLHttpRequest();
//2:设置请求行
//判断type类型和data是否有值
if(option.type=="get"&&option.data){
url+="?";
url+=option.data;
}
xhr.open(option.type,url);
//3:设置请求头(get及post无数据可不写)
//判断type类型和是否有数据
if(option.type=="post"&&option.data){
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
}
//4:回调函数
xhr.onreadystatechange=function(){
//判断数据是否返回成功
if(xhr.readyState==4&&xhr.status==200){
//判断返回数据的类型:json,xml,普通文本
//获取文档类型
var datatype=xhr.getResponseHeader('Content-type');
if(datatype.indexOf('json')!=-1){
//通过json.parse()方法转换为json对象
option.success(JSON.parse(xhr.responseText));
}else if(datatype.indexOf('xml')!=-1){
//返回xml类型数据
option.success(xhr.responseXML);
}else{
//不是json或则xml返回 普通文本
option.success(xhr.responseText);
}
}
}
//5:请求体,发送数据
//判断type类型及是否有数据
if(option.type=="post"&&option.data){
data=option.data;
}
xhr.send(data);
}
调用:
在实际使用中无需自己进行封装,在此只是阐述演示一下封装的作用,思路,过程。原生ajax使用也相当少,大部分框架都对ajax进行了封装,提供了相应的方法,如jquery等。使用框架提供的ajax方法,可以有效的提高ajax开发速度,降低难度,解决兼容性问题等。下一章以jq为例,详细整理了jq中ajax的使用。链接底部。
ajax(序章)同步与异步:同步与异步(小白必看,大神略过)
ajax(末章)jq中的ajax,ajax跨域,xml/json。点击打开链接