乐趣区

突破Ajax请求

==> 本人的文章不代表权威与正确,纯属个人理解,如有差池万望斧正 <==

Ajax 的介绍

Ajax 请求是现代网页最重要的构成元素之一,通过这项技术,用户可以在不重载整个页面的情况下,完成局部数据的交互与刷新。如果这项功能不存在,那每一次向服务器申请数据,所有内容都需要重新下载、排列。
虽然听上去这是一个凌驾于网页规则之上的高阶技术。但本质上它仍然是 http 请求,或者说主要以该请求为载体,这个请求可以具备 HTTP 请求的所有特征,如:请求行,请求头,请求体。并开放了一些可供开发者自定义的内容。我们不需要关心 XMLHttpRequest 实例的具体实现方式,只需要了解——这个请求帮你向服务器传达什么?它返回的响应如何处理?
Ajax 请求一般以 DOM 的某个事件驱动,如加载完毕,点击等

Ajax 的流程

一个完整的 Ajax 具有以下 4 个执行步骤:

1,创建实例
Ajax 通过 XMLHttpRequest() 的实例来实现,其中 XML 是一种经典的、标准的、兼容性强的数据存储格式。但当下的主要网络传输方式,大都以更加轻量、易读的 JSON 进行。IE6 及 IE5 并不支持该实例的创建,如果考虑到兼容上述浏览器,可以创建 ActiveXObject(“Microsoft.XMLHTTP”) 实例。常用的兼容写法如下:

try{var xhr = new XMLHttpRequest()
}catch{var xhr = new ActiveObject('Microsoft.XMLHTTP')
}
--------------------------
var xhr
if(window.XMLHttpRequest){xhr = new XMLHttpRequest()
}else{xhr = new ActiveObject('Microsoft.XMLHTTP')
}

2,定义请求内容
通过实例.open(请求方法,请求 URL,是否异步) 定义请求的发送方式和内容,与 HTTP 请求不同的是,Ajax 仅可以使用 get 或 post 两种请求方法;请求 URL 同 HTTP 标准;请求行中,用于填写协议版本的部分,此处可以忽略或写入一个布尔值。布尔值默认为 true,此时请求被异步处理,如果为 false 则进行同步处理。

当同步处理进行时,页面的其他行为将陷入停滞无法被触发,因为 JS 的线程正在被占用,直到 Ajax 收到响应数据或失败结果后才会恢复。这种请求可用于移动端 APP,你在看到滚动条或 loading 图时,任何动作都不会被浏览器捕获到,因为此时的浏览器无暇顾及你的其他命令。
虽然 JS 是单线程,但浏览器不是,所以当异步操作时,发送后进入等待状态的 Ajax 会被浏览器开启另一个线程挂起,收到回复后,会把这个 Ajax 结果放回 JS 主线程队列的末端。这时不会影响到页面的其他行为。如:在视频缓存的同时,仍然可以查看陈大脸先生播放列表里都是哪些老师的作品。

xhr.open('GET','http://www.nichousha.com',true)
  • 定义请求头

实例.setRequestHeader(请求头键,请求头值) 基本不会用到的方法,但它的存在能够强化对 Ajax 本质的了解,即 Ajax 是一种具有较高完整度的,特殊的 HTTP 请求,你可以只定义几个关键内容就能正常地发送了。

3,发送请求
实例.send(请求体) 可以发送这次请求,如果请求的方法是 post,此处可以写入请求体。如果向服务器发送的请求不涉及过于复杂的内容。此处可以 send 空值并使用 get 方法加问号传参的方式发送。为了保障兼容性,如果 get 方法发送空值,此处建议写入 null。如:实例.send(null)

xhr.send(null)

4,接收并处理响应
确认 Ajax 是否收到结果取决于两个具体条件:Ajax 状态码和 http 请求状态码。这个判断由 onreadystatechange 触发,每当 Ajax 进行到一个阶段都会触发这个状态码改变事件,并产生一次判断,Ajax 对应 0 - 4 共 5 个状态码:
(0)未初始化
(1)正在 send 发送
(2)完成 send 发送
(3)请求处理中
(4)请求完成或失败,已收到确切响应
Ajax 状态码(readyState)结果一定为 4,才能判定为成功。此时我们还无法证实它是否带回了我们想要的结果,因为它可能兴致冲冲地迎上去,却遭遇了 404 这种不友善错误的无情拒绝。所以这时还需要第二层判断:http 请求状态码(status)
如果请求被顺利返回,此时的 http 状态码一定是 200。
* 假如缺少对 http 请求状态码的二次判断,onreadystatechange 会分别在 Ajax 状态码 1,2,3 的改变事件触发后进行完整的 Ajax 结果处理,相当于你在碗里什么东西都没有的情况下进食了约 45 分钟。

xhr.onreadystatechange = function(){if(xhr.readyState == 4 && xhr.status == 200){// 处理结果}
}

Ajax 的钩子

ES 标准中,还定义了一部分 Ajax 实例发送过程的阶段型事件。常用的:如强制终止,最大时限,对不同结果的处理等 …

绝对事件:

1. 实例.onloadstart
当 Ajax 请求被发起,就会触发这个钩子

2. 实例.onprogress(event)
进度访问,该钩子可以周期性地访问两个属性:loaded 和 total(当前量传输和总量)一般用于显示一个较大文件的上传进度。

2. 实例.onloadend
无论成功或是失败,Ajax 最终都会获得一个必然结果,并触发这个钩子。

3. 实例.onload
成功地获取了预期的请求结果。

4. 实例.onerror
返回的实例并不是一个正确的结果

意外事件:

1. 实例.ontimeout
设置最大时限,配合 实例.timeout = 毫秒数,当 Ajax 超时,触发这个钩子

2. 实例.onabort
请求终止,当实例.abort()终止请求时,触发该钩子

xhr.timeout = 1000;
xhr.ontimeout = function(){alert('已超时')
}

Ajax 的结果处理

Ajax 获得的结果主要为两类,XML 或 JSON,前者可以使用 responseXML 直接解析为 DOM 对象。JSON 则可以被 responseText 转换为字符串格式

退出移动版