AJAX
要想要知道AJAX是什么呢,首先要知道一般情况下客户端都会从服务器获取了一些什么类型的文件;
- 如果客户端在服务器需要获取的是资源文件,浏览器会自动帮我们向服务器发送请求,并且接收服务器返回的内容进行渲染,最终显示出来;(这里的资源文件包括JS,HTML,CSS,IMG等类型)
向服务器发送请求资源文件基本可通过:
- 在地址栏输入网址
- 利用LINK
- 利用SCRIPT
- 利用IFRAME
- ...
- 但是如果我们需要向服务器请求的是数据(这里的数据可能是json、text、xml等格式的),就需要使用AJAX等技术发送请求了(AJAX是JS中的一个核心重要知识点)
‘AJAX 不是新的编程语言,而是一种使用现有标准的新方法。’ ---W3C的官方解释
所以什么是AJAX:
AJAX: Async(Asynchronous) JavaScript And Xml
翻译过来就是 :异步的JavaScript和Xml
来自W3C的解释:
AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 那么什么又是XML
- AJAX叫做异步更新,难道使用异步请求吗?
扫盲1 : 什么是XML
- html :超文本标记语言,W3C制定了很多具有语义化的标记标签,我们使用这些HTML标签搭建页面结构(目前用的比较多的是 v4/v5(HTML5)版本)
- xhtml:更加严格的HTML (用的比较少了)
- dhtml:页面中的数据是动态绑定的 (非官方标准语言)
- xml :可扩展的标记标签语言,它里面使用的标签都是自己定义的,也不是W3C的规范标签
- 我们可以使用自己定义的有意义的标签来存储数据,这样结构清晰明了(目前前端数据存储和展示一般都使用JSON,但是之前一般都是XML)
以前项目中服务器返回给客户端的数据类型一般都是XML格式的,只不过XML格式的数据在客户端的二次解析过程中相对于JSON比较麻烦,现在服务器端返回给客户端的数据一般都是JSON格式的数据;但是也有XML格式的数据;
- wxml:微信小程序的页面就是.wxml ,小程序中使用的标签都是小程序自己定义的(微信XHML)
扫盲2 :异步JS -> 异步更新
在web1.0 web2.0时代初期, ==> 整体刷新
前端页面中的功能和数据绑定大部分都是后台开发者使用后台语言来完成的;浏览器只有一个作用,就是把后台实现好的功能的页面呈现即可,所有的操作都是后台在服务器完成的;这样的话如果前端页面中的内容需要改变的话,必须后台重新把最新的内容返回,前端需要重新呈现,导致整个前端页面都刷新;
AJAX 里的Async(异步)先不要理解为JS中的同步异步编程(这样会很混乱),这里面的异步可以先理解为‘局部刷新’,如果用七个字概述AJAX的作用,那就记住 “实现局部刷新的” 就Ok了;
举一个非常简单的运用AJAX的例子:
注册百度账号页面中,
【运用AJAX】注册过程中,如果填写一个已经被注册的手机号,此时,在点击验证码选框时,该手机号的数据内容便会传送到服务器端进行验证,会立马弹出此手机已经被绑定过的提示框;
【没有运用AJAX】整个数据传输过程中不会有任何提示框出现,只有在全部表单填写完成点击注册后完成一次数据传输,与服务器建立连接进行确认,如果此时该手机被注册的话,整个注册页面会被重新刷新后才会返回该手机被绑定的数据信息,并且之前表单中填写信息都在刷新后清空,体验极差,所以一般此类页面为了增加用户体验都会运用到AJAX;当然还有很多运用场景...
简单实现AJAX的基本步骤
1、 创建AJAX对象
var xhr = new XMLHttpRequest(); // ->IE6 下不兼容 不兼容用 new ActiveXObject
2 、打开一个请求的URL地址
xhr.open([method],[request url],[async/sync]);
- [method] : 请求方式分为两大系列:
- get系列:
- get : 获取 (应用于从服务器端获取内容)
- delete :删除,应用于删除服务器上的内容
- head :应用于只想获取服务器响应头信息
- post系列:
- post : 推送,应用于给服务器推送内容
- put : 放,应用于在服务器上放文件等
- ...
- 还有更多的请求方式
ps: 以上的几种方式,客户端都可以把内容传递给服务器,服务器也可以把内容返回给客户端,只不过在不同的场景,我们使用对应的类型会更好一些,以上没有硬性规定,方式可以互换。只不过大家形成了一种约定俗成的默契,例如:
给服务器少,从服务器拿的多,我们最好用GET请求
给服务器多,从服务器拿的少,我们最好用POST请求
get请求和post请求的区别:
核心:
- get请求传递给服务器的内容是通过问号传参的方式传递的;
xhr.open('get','temp.json?xxx=xxx&xxx=xx') - post传递给服务器的内容是用过请求主体传递的 ;
xhr.send(...)
(1) GET传递给服务器的内容没有POST请求多 :
每一个浏览器对url的长度都有限制(谷歌8kb、火狐7kb、ie2kb),如果get请求下传递的比较多,url就会超出限制,超出的限制部分浏览器自动截取,导致服务器获取的内容不完整;
而请求主体中的大小理论上是没有限制的,但真实项目中为了保证传输的速度,我们会限制传递内容的大小.
(2) GET请求容易出现缓存 :
还是因为使用问号传参的方式,如果重复向同一个地址发送请求,传递的参数值都是一样的,浏览器会默认的给做缓存(这个缓存不可控),所以我们一般项目中在使用get请求的时候都要把缓存清除掉;
xhr.open('get','temp.json?_='+Math.random());
(3) GET请求相对于POST来说不安全 :
有一种黑客技术叫做‘url劫持’,被劫持后,问号后面的参数值都会被获取或者修改,导致不安全
- [request url] :请求数据的接口地址,客户端也是通过这个地址向服务器发送请求的,客户端可以通过问号传参的方式吧内容传递给服务器;
xhr.open('get','temp.json?name = zhangsan&age=18',true);
-
[async/sync] : 同步或者异步,默认true 代表异步,可不写;
在真实项目中,为了防止出现请求堵塞的问题,我们大部分采用的是异步
比如请求文件比较大,如果时间很长,响应时间比较长就会影响后面的数据
3 、监听AJAX状态改变,在不同的状态下处理不同的事情
xhr.onreadystatechange = function(){
if(xhr.readyState===4 && xhr.status ===200){
var val = xhr.responseText;
// -> xhr.getResponseHeader([key]) 获取响应头信息
// -> xhr.responseText: 获取的是字符串(一般是服务器响应主体
//返回的JSON字符串)
// -> xhr.responseXML: 获取的是XML数据
}
}
xhr.readyState :AJAX状态码
0 UNSENT : 未发送,刚开始创建完成AJAX对象,默认的状态就是0
1 OPENED : 已打开,执行了xhr.open之后状态变为1
2 HEADERS_RECEIVED :响应头信息已经成功的返回并且被接收
3 LOADING : 响应主体内容正在加载
4 DONE :响应主体内容接收成功
- xhr.status : 服务器返回的HTTP网络状态码
200 : 请求成功
【 3 开头的都是成功但是有转折】
301 : 永久重定向(永久转移) 例如:访问京东以前的域名www.360buy.com;
在控制台network里,可以看到301,域名更换的时候我们基本上都会做301做永久的重定向;
302 : 临时重定向(临时转移) --> 307(临时重定向) ;例如:一台服务器最高并发数在500左右,当501个人过来的时候,当前服务器不能有效的进行处理了,此时我们需要把此客户端的请求临时转移到另外一台服务器上进行处理;
304 : 读取的是缓存的数据,在真实的项目中,产品一旦上线,资源图片、JS、CSS等内容是不轻易改变的,此时我们最好做一下304缓存:第一次向服务器发送请求来访问的时候,把加载完成的资源文件进行缓存,第二次直接读取缓存中的数据即可,减少服务器压力;
【4开头的一般都是客户端的错误】
400 请求参数有误
401 请求的权限不够
404 请求的地址不存在
【服务器端的错误】
500 未知的服务器端错误 (停电,着火,服务器爆炸等等不可预知错误....)
503 服务器超负荷 (春运抢票的时候你一定会看到这个状态)
4 、发送AJAX请求给服务器
xhr.send(null);
// -GET系列请求传递的一般都是null,因为他们通过问号传参把内容传递给服务器
// -POST系列的请求会把需要传递给服务器的内容放在这里(请求主体);
AJAX整个过程中开始和结束标志事件:
开始的标志:xhr.send(...)
结束的标志:xhr.readyState === 4
利用JQuery 实现AJAX
<script src="jquery.min.js"></script>
$.ajax({
url: 'temp.json',
method: 'get',
//->type:'get' 和这个属性是一样的功能的,除了写get还可以写post、head、delete、put...
dataType: 'json',
//->预设服务器返回的数据内容的格式json(默认)、text、xml...
data: null,
//->设置请求主体的内容,如果是GET请求,JQ会把这些内容放到请求地址的末尾,通过问号传参的方式传递给服务器,POST请求才是放在请求主体中
cache: true,
//->是否保留GET请求的缓存,TRUE是保留也就是不清除GET缓存,设置成为FALSE是清除缓存(在URL末尾加随机数),此参数对于POST请求无效
async: true,
//->设置同步异步,默认是TRUE代表异步
//timeout:3000,//->设置请求超时的时间,如果超过3000MS,当前请求自动中断(一般不用)
success: function (result) {
//->当数据请求成功后执行的回调函数,result就是从服务器获取的结果
console.log(result);
},
error: function (msg) {
//->当数据请求失败指定的回调函数,msg就是失败的原因
}
});
// JQ中的参数配置大概在20多个左右,以上只是最常用的几个
/*
* [data]
* get->放在URL末尾
* post->放在请求主体
*
* 字符串->写的是什么传递就是什么
* 对象->会把对象变成 key1=value1&key2=value2... 传递给服务器
*/
最后分享一道面试题:
问:有做过类似于倒计时的项目吗,做的时候当前时间是从客户端本地读取的还是从服务器读取的?从服务读取时间你是怎么解决时间差的?
<script>
/*
* 获取服务器的时间,我们不需要再响应主体中获取,在响应头的信息中,
* 有一个叫做Date的属性,它存储的值就是服务器的时间
*/
var xhr = new XMLHttpRequest();
xhr.open('head', 'temp.xml?_=' + Math.random());
//->为什么选择HEAD请求方式?因为当前的需求,我们只想获取到服务器时间,
//这样的话只需要把响应头信息获取到即可,主体内容不需要获取了,
//使用HEAD就是只获取头信息,加大请求的效率;
xhr.onreadystatechange = function () {
if (xhr.status !== 200) return;
if (xhr.readyState === 2) {
//->我们只需要响应头信息返回就可以获取到服务器的时间,如果等到4的时候,
//虽然也可以获取到,但是间隔的时间更长了,导致时间差也会变大(真实时间和服务器获取的时间差值)
var time = xhr.getResponseHeader('Date');
//->获取到的时间是格林尼治时间(GMT),我们还需要把这个时间变为北京时间(GMT+0800)
time = new Date(time);
console.log(time);
}
};
xhr.send(null);
</script>
以上就是对AJAX的一个初步的探索啦,这技术出道这么久,一直只闻其名不见其声的技术,还真有点相见恨晚的赶脚啊....
相信初学者看完此篇应该会对AJAX有一个初步的理解了,目前也探索到这里,一起继续探索吧,骚年们,如有异议,欢迎指正~!