一、什么是AJAX,为什么要使用Ajax(请谈一下你对Ajax的认识)
ajax全称(异步的javascript和XML),为什么会有这么一种技术的出现呢,因为前端时常会有这样的需求,我们只要局部刷新,不需要整一个刷新的时候,便催生了这样的技术。
在 Ajax应用中信息是通过XML数据或者字符串在浏览器和服务器之间传递的(json字符串居多)
在浏览器端通过XMLHttpRequest对象的responseXMl属性,得到服务器端响应的XML数据。
AJAX优点:
最大的一点是页面无刷新,用户的体验非常好。
使用异步方式与服务器通信,具有更加迅速的响应能力。
可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
AJAX缺点:
ajax不支持浏览器back按钮。
安全问题 AJAX暴露了与服务器交互的细节。
对搜索引擎的支持比较弱。
破坏了程序的异常机制。
不容易调试。
AJAX应用和传统Web应用有什么不同?
传统的web前端与后端的交互中,浏览器直接访问Tomcat的Servlet来获取数据。Servlet通过转发把数据发送给浏览器。
当我们使用AJAX之后,浏览器是先把请求发送到XMLHttpRequest异步对象之中,异步对象对请求进行封装,然后再与发送给服务器。服务器并不是以转发的方式响应,而是以流的方式把数据返回给浏览器
XMLHttpRequest异步对象会不停监听服务器状态的变化,得到服务器返回的数据,就写到浏览器上【因为不是转发的方式,所以是无刷新就能够获取服务器端的数据】
AJAX是异步执行的,如图所示,异步执行不会阻塞.
二、ajax 的执行过程
创建XMLHttpRequest对象,也就是创建一个异步调用对象
创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
设置响应HTTP请求状态变化的函数
发送HTTP请求
获取异步调用返回的数据
使用JavaScript和DOM实现局部刷新
基本示例:
简单应用示例:
2.1 `open()`方法
调用open方法并不会真正发送请求,而只是启动一个请求以备发送。
它接受三个参数:
要发送的请求的类型
请求的URL
表示是否异步的布尔值。
2.2 `send()`方法
如果要发送请求,用方法。
要发送特定的请求,需要调用send()方法。
它接受一个参数:请求主体发送的数据。
如果不需要通过请求主体发送数据,则必须传入null,不能留空。
请求主体:HTTP上行请求,有头部、主体。
一般来说,GET请求是只有头部,没有主体
而POST请求有请求主体。
一但调用send()方法,HTTP上行请求就将发出。
2.3 `readyState`属性
表示“就绪状态”
0 (uninitialized) 未初始化
1 (loading) XMLHttpRequest对象正在加载
2 (loaded) XMLHttpRequest对象加载完毕
3 (interactive) 正在传输数据
4 (complete) 全部完成
一般来说,只需要使用4状态就可以了
只要这个属性值发生了变化,就会触发一个事件事件,就可以使用来捕获变化之后做的事情。
三、关于http的状态
ajax 也是使用 http 协议的,所以也需要了解 http协议的状态。
这是比较齐全的状态表:
四、关于函数封装(ajax封装)
变量、函数的作用域,是定义这个变量、函数时,包裹它的最近父函数。
没有在任何function中定义的变量,称为全局变量。全局变量都是window对象的属性。所以,如果想在函数内,向全局暴露顶层变量,只需要把顶层变量设置为window对象的属性。
越是大的项目,越需要让全局变量越少越好。这是为了防止不同工程师之间的程序,命名冲突。所以,每一个功能包,只能向全局暴露唯一的顶层变量,就是这个功能包自己的命名空间。
jQuery、YUI、underscore都是这样的做法。
向外暴露全局变量,设置window的变量(也是这个函数的命名空间),类似jquery的其实也就是
良好的代码风格
`//=======================属性=======================`
`//=======================方法=====================`
`//=======================内部方法=====================`
`_`代表内部方法或者属性,主要是给编程人员看的
属性和方法写在前面,内部属性或者内部方法写在后面
通过判断来实现函数重载
五、关于ajax缓存问题
当Ajax第一次发送请求后,会把请求的URL和返回的响应结果保存在缓存内,当下一次调用Ajax发送相同的请求时,注意,这里相同的请求指的是URL完全相同,包括参数,浏览器就不会与服务器交互,而是直接从缓存中把数据取出来,这是为了提高页面的响应速度和用户体验。(服务端也会收到请求响应304)
浏览器会自作主张的把所有异步请求来的文件缓存,当下一次请求的URL和之前的一样,那么浏览器将不会发送这个请求,而是直接把缓存的内容当做。
需要注意的是,post 请求方式不会被缓存,只有 get 请求方式会被缓存。
5.1 如何避免 ajax 缓存问题
方法1:随机数
方法2:时间戳
从1970年1月1日0:00到这一刻的毫秒数。就叫做时间戳。英语属于timestamp。
JS里面时间戳就是
总的来说,原理就是通过将 get 请求的 url 做成每次都不一样,这样就不会被浏览器缓存了。
六、json检测
判断返回的 json 数据是否可用,这个只是属性一些日常使用 ajax 的点而已。
6.1 使用 JSON.parse
通过转换为json格式,如果无法转换,会报错。
6.2 用hasOwnProperty进行判断
hasOwnProperty 这个方法能够判断对象里面是否有某个键属性。
这个示例比较详细,并且加入了错误之后的处理:
七、关于跨域问题
已经在另外一篇文章里面说过了,jsonp 是其中一种解决办法。
blog:https://www.godblessyuan.com/2018/07/jsonp-反向代理-CORS解决JS跨域问题的个人总结(更新%20v2.0).html
7.1 使用jsonp
八、关于ajax的示例:瀑布流
要实现2个地方:
滚动到底部判断(包含视口的底部和总的底部)
瀑布流里面的内容需要错位显示
8.1 滚动到底部判断
我们需要知道:
总文档高度
已经滚动的高度
视口高度,通过 获取,视口底部来触发ajax 获取下一页的数据
总文档高度-已经卷动高度-视口高度
scroll事件,一定是要截流的。因为用户滚一个鼠标滚轮的“小咯噔”就触发一次scroll事件;滑动滚动条的时候,是每一像素触发一次这个事件。还有pageDown、下箭头按钮,都能触发scroll事件。
如何判断文章是否到头,说白了前端开发工程师不知道一共有多少页。比如今天又53页,明天就有55页了,所以你的JS里面无法写死一个文章总页数。所以办法就是,请求下去,请求到page.php?pagenum=54的时候,发现终止标记,或者这个页面返回的json是空,就表示到头了。
8.2 瀑布流里面的内容需要错位显示
这里分成三列瀑布流,组成一个数组管理
这个数组会不断计算三列之中的最小值
然后按照每次的最小值进行高度插入
图片判断是否加载完成需要用load方法,并且图片需要先new image才能加载方法
图片的插入次序不是固定的(ajax异步),所以用之前的数组进行管理,每次都对最小值的高度插入值,这样就能保证每次都往最靠里面的图片位置进行放置
并且需要使用绝对位置值,因为css里面,需要使用绝对值撑开位置(left 和top)
瀑布流的数组样例如下:
8.3 整个代码
领取专属 10元无门槛券
私享最新 技术干货