AJAX基础知识及核心原理解读
AJAX基础知识
什么是AJAX?
async javascript and xml 异步的JS和XML
XML:可扩展的标记语言
作用:是用来存储数据的(通过自己扩展的标记名称清晰地展示出数据结构)
ajax之所以称为异步的js和xml,主要原因是:以前最开始使用ajax实现客户端和服务端数据通信的时候,传输数据的格式一般都是xml格式的数据,我们把他称之为异步的js和xml(现在一般都是基于JSON格式来进行数据传输的)
1 |
|
异步的JS
这里的异步不是说ajax只能基于异步进行请求(虽然建议都是使用异步编程),这里的异步特指的是 局部刷新
局部刷新 VS 全局刷新
全局刷新:
在非完全前后端分离的项目中,前端开发只需要完成页面的制作,并且把一些基础的人机交互效果使用js完成即可,页面中需要动态呈现内容的部分,都是交给后台开发工程师做数据绑定和基于服务器进行渲染的(服务器端渲染)
【优势】
- 动态展示的数据在页面的源代码中可以看见,有利于SEO优化推广(有利于搜索引擎的收录和抓取)
- 从服务器端获取的结果已经是解析渲染完成的了,不需要客户端再去解析渲染了,所以页面加载速度快(前提是服务器端处理的速度够快,能够处理过来),所以类似于京东,淘宝这些网站,首屏数据一般都是由服务器端渲染的
【弊端】
- 如果页面中存在实时更新的数据,每一次想要展示最新的数据,页面都要重新刷新一次,这样肯定不行,非常耗性能
- 都交给服务器端做数据渲染,服务器端的压力太大,如果服务器处理不过来,页面呈现的速度更慢(所以像京东和淘宝这类的网站,除了首屏是服务器端渲染的,其他屏一般都是客户端做数据渲染绑定的)
- 这种模式不利于开发,(开发效率低)
局部刷新
目前市场上大部分项目都是前后端完全分离的项目(也有非完全前后端分离的占少数)
前后端完全分离的项目,页面中需要动态绑定的数据是交给客户端完成渲染的
- 向服务器端发送AJAX请求
- 把从服务器端获取的数据解析处理,拼接成我们需要展示的HTML字符串
- 把拼接好的字符串替换页面中的某一部分内容(局部刷新),页面不需要整体重新加载,局部渲染即可
【优势】
我们可以根据需求,任意修改页面中的某一部分内容(例如实时刷新),整体页面不刷新,性能好,体验好(所有表单验证,需要实时刷新的等需求都要基于AJAX实现)
有利于开发,提高开发效率
1)前后端的完全分离,后台不需要考虑前端如何实现,前端也不需要考虑后台用什么技术,真正意义上实现了技术的划分
2)可以同时进行开发:项目开发开始,首先制定前后端数据交互的接口文档(文档中包含了,调取哪个接口或者哪些数据等协议规范),后台把接口先写好(目前很多公司也需要前端自己拿NODE来模拟这些接口),客户端按照接口调取即可,后台再去实现接口功能即可
【弊端】
- 不利于SEO优化:第一次从服务器端获取的内容不包含需要动态绑定的数据,所以页面的源代码中没有这些内容,不利于SEO收录,后期通过JS添加到页面中的内容,并不会写在页面的源代码中(是源代码不是页面结构)
- 交由客户端渲染,首先需要把页面呈现,然后在通过JS的异步AJAX请求获取数据,在进行数据绑定,浏览器再把动态增加的部分重新渲染,无形中浪费了一些时间,没有服务器端渲染页面呈现速度快
基于原生JS实现AJAX
1 | // 创建一个AJAX对象 |
分析第二步中的细节点
xhr.open([method],[url],[async],[userName],[passWord])
[AJAX请求方式]
- GET请求系列(获取)
- get
- delete:从服务器上删除某些资源文件
- head:只想获取服务器返回的响应头信息(响应主体不需要获取)
- POST请求系列(推送)
- post
- put:向服务器中增加指定的资源文件
不管哪一种请求方式,客户端都可以把信息传递给服务器端,服务器端也可以把信息返回给客户端,只是GET系列一般以获取为主(给的少,拿回来的多),而POST系列一般以推送为主(给的多,拿回来的少)
1)我们想要获取一些动态展示的信息,一般使用GET请求,因为只需要向服务器端发送请求,告诉服务器端我们想要什么,服务器端就会把需要的数据返回
2)在实现注册功能的时候,我们需要把客户输入的信息发送给服务器进行存储,服务器一般返回成功或失败等状态,此时我们一般都是基于POST请求完成的
GET系列请求和POST系列请求,在项目实战中存在很多的区别
GET请求传递给服务器的内容一般没有POST请求传递给服务器的内容多
原因:GET请求传递给服务器内容一般都是基于 URL地址问号传递参数 来实现的,而POST请求一般都是基于 设置请求主体 来实现的,各个浏览器都有URL最大长度的限制(谷歌:8kb,火狐:7kb,IE:2kb),超出长度部分,浏览器会自动截取掉,导致传递给服务器的数据缺失
理论上POST请求通过请求主体传递是没有大小限制的,真实项目中为了保证传输的速率,我们也会限制大小(例如:上传的资料或者图片我们会做大小的限制)
GET请求很容易出现缓存(这个缓存不可控,一般我们都不需要),而POST不会出现缓存(除非自己做特殊处理)
原因:GET是通过URL问号传参传递给服务器信息,会出现缓存;而POST是设置请求主体,不会出现缓存。
1 | // 每隔一分钟重新请求服务器端最新的数据,然后展示在页面中(页面中某些数据实时刷新) |
GET请求没有POST请求安全(POST也并不是十分安全,只是相对安全)
原因:还是因为GET是URL传参给服务器
有一种比较简单的黑客技术:URL劫持,也就是可以把客户端传递给服务器的数据劫持到,导致信息泄露
URL:请求数据的地址(API地址),在真实项目中,后台开发工程师会编写一个API文档,在API文档中汇总了获取哪些数据需要使用哪些地址,我们按照文档操作即可
ASYNC:异步(SYNC 同步),设置当前AJAX请求是异步的还是同步的,不写默认是异步(TRUE),如果设置为FALSE,则代表当前请求是同步的
用户名和密码:这两个参数一般不用,如果你请求的URL地址所在的服务器设定了访问权限,则需要我们提供可通行的用户名和密码才可以(一般服务器都是可以匿名访问的)
分析第三步中的细节点
AJAX状态码:描述当前AJAX操作状态的:
xhr.readyState
0:UNSENT未发送,只要创建一个AJAX对象,默认值就是零
1:OPENED 我们已经执行了xhr.open这个操作
2:HEADERS_RECEIVED 当前AJAX的请求已经发送,并且已经接收到服务器端返回的响应头信息了
3:LOADING 响应主体的内容正在返回的路上
4:DONE 响应主体内容已经返回到客户端
HTTP网络状态码:记录了当前服务器返回信息的状态 :
xhr.status
200:成功,一个完整的HTTP事务完成(以2开头的状态码一般都是成功)
以3开头一般也是成功,只不过服务器端做了很多处理
301:Moved Permanently 永久转移(永久重定向),一般应用于域名迁移
302:Move temporarily 临时转移 (临时重定向,新的HTTP版本中任务307是临时重定向),一般用于服务器的负载均衡:当前服务器处理不过来,把当前请求临时交给其他的服务器处理(一般图片请求经常出现302,很多公司都有单独的图片服务器)
304:Not Modified 从浏览器缓存中获取数据。把一些不经常更新的文件或者内容缓存到浏览器中,下一次从缓存中获取,减轻服务器压力,也提高页面加载速度
以4开头的,一般都是失败,而且客户端的问题偏大
400:请求参数错误
401:无权限访问
404:访问地址不存在
以5开头的,一般都是失败,而且服务器端的问题偏大
500:Internal Server Error 未知的服务器错误
503:Service Unavailable 服务器超负载
AJAX中其他常用的属性和方法
面试题:AJAX中总共支持几个方法?
1 | let xhr = new XMLHttpRequest(); |
例子:
1 | let xhr = new XMLHttpRequest(); |
JS中常用的编码和解码方法
正常的编码解码(非加密)
- escape / unescape: 主要就是把中文汉字进行编码和解码(一般只有JS语言支持:也经常应用于前端页面通信时候的中文汉字编码)
1 | str = '你好海洋 哈哈' |
- encodeURI / decodeURI : 基本上所有的编程语言都支持
1 | str = '你好海洋 哈哈' |
encodeURIComponent / decodeURIComponent 和第二种方式非常类似,区别在于:
当我们通过URL问号传参的时候,我们传递的参数值还是一个URL或者包含很多的特殊字符,此时为了不影响主要的URL,我们需要把传递的参数值进行编码,使用encodeURI不能编码一些特殊字符,所以只能使用恩codeURLComponent处理
1 | str = '你好海洋 哈哈' |
1 | let str = 'http://wudiufo.github.io/?', |
也可以通过加密的方法进行编码解码
可逆转加密(一般都是团队自己用的规则)
不可逆转加密(一般都是基于MD5完成的,可能会把MD5加密后的结果二次加密)
AJAX中的同步和异步编程
AJAX这个任务:发送请求接收到响应主体内容(完成一个完整的HTTP事务)
xhr.send() : 任务开始
xhr.readState===4 : 任务结束
1 | let xhr = new XMLHttpRequest(); |
1 | let xhr = new XMLHttpRequest(); |
1 | let xhr = new XMLHttpRequest(); |
1 | let xhr = new XMLHttpRequest(); |
1 | let xhr = new XMLHttpRequest(); |
1 | let xhr = new XMLHttpRequest(); |
实战案例:倒计时抢购
1,结构:
1 |
|
2, 交互:
1 | ~ function() { |
AJAX类库的封装
JQ中AJAX操作详解
1 | $.ajax({ |
封装属于自己的AJAX类库
【支持的参数】
url
method/type
data
dataType
async
cache
success
1 | ~ function() { |
优化代码:
1 | ~ function() { |