文章目录
一、Ajax
1. 介绍
- Ajax指一种创建交互式网页应用的网页开发技术。
- 它可以令开发者只向服务器获取数据(而不是HTML文档等资源)
(1)特点
- 在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。
- 由于Ajax请求获取的是数据而不是HTML文档,因此它也节省了网络带宽。
(2)原理
- 其中最核心的依赖是浏览器提供的
XMLHttpRequest
对象。 - 简单来说,Ajax就是通过JS发送请求、接收响应,是对浏览器提供的接口进行封装。
2. Ajax核心
(1)创建XMLHttpRequest
对象
var xhr = new XMLHttpRequest();
(2)向服务器发送请求
xhr.open(method,url,async);
send(string);//post请求时才使用字符串参数,否则不用带参数。
method
:请求的类型;GET 或 POSTurl
:文件在服务器上的位置async:true
(异步)或false
(同步)
注意:post请求一定要设置请求头的格式内容
代码实例
xhr.open("POST","test.html",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("fname=Henry&lname=Ford"); //post请求参数放在send里面,即请求体
(3)处理服务端响应
同步处理
xhr.open("GET","info.txt",false);
xhr.send();
document.getElementById("myDiv").innerHTML=xhr.responseText; //获取数据直接显示在页面上
异步处理
xhr.onreadystatechange=function() {
if (xhr.readyState===4 &&xhr.status===200) {
document.getElementById("myDiv").innerHTML=xhr.responseText;
}
}
- 当
xhr.readyState === 4
的时候,说明请求结束; - 这个时候查看HTTP状态码,如果
xhr.status === 200
,说明请求成功,已经获取到服务端数据,将数据渲染到页面上。
(4)readyState(XHR状态)
- readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
- readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义
- 0:未初始化 – 尚未调用.open()方法;
- 1:启动 – 已经调用.open()方法,但尚未调用.send()方法;
- 2:发送 – 已经调用.send()方法,但尚未接收到响应;
- 3:接收 – 已经接收到部分响应数据;
- 4:完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了;
(5)status(HTTP状态码)
- HTTP状态码(status)由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。
- 当状态码为200,即表示请求成功。
3. Ajax请求实现(原理)
- 创建
XMLHttpRequest
对象 - 调用send方法发送 Http请求
- 监听xhr对象状态变化,JS引擎可以执行其他任务
- 等到
readyState
属性值为4,status
属性值为200,就将回调函数放到任务队列中排队执行。
function ajax(url, fnSucc, fnFaild) {
var xhttp;
// 第一步:创建XMLHttpRequest对象
if (window.XMLHttpRequest) {
// 现代浏览器
xhttp = new XMLHttpRequest();
} else {
// IE6等老版本浏览器
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
// 第二步:初始化XMLHttpRequest方法
xhttp.open('GET', url);
// 第三步:XMLHttpRequest向服务器发送请求
xhttp.send();
// 第四步:处理响应
xhttp.onreadystatechange = function() {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
fnSucc(xhttp.responseText)
} else {
if (fnFaild) fnFaild(xhttp.responseText)
}
}
}
}
4. 总结特性
- 就是不跳转不刷新的情况下,在网页后台提交数据,部分更新页面内容,将页面的用户体验提升到接近原生程序的程度。
- 第一次下载可能慢一点,但以后操作只与服务器交换关键数据。减轻服务器的负担同时页提高了客户端运行的流程性。
- 因为ajax技术是动态加载内容,所以不利于SEO。(单页面应用)
二、XMLHttpRequest(XHR)
1. 简介
- XMLHttpRequest 一开始只是微软浏览器提供的一个接口,后来各大浏览器纷纷效仿也提供了这个接口。后来W3C对它进行了标准化,提出了 XMLHttpRequest标准。
- XMLHttpRequest 标准又分为Level 1 和Level 2。
2. 版本对比
Level 1的缺点
- 受同源策略的限制,不能发送跨域请求;
- 不能发送二进制文件(如图片、视频、音频等),只能发送纯文本数据;
- 在发送和获取数据的过程中,无法实时获取进度信息,只能判断是否完成;
Level 2 改进
- 可以发送跨域请求,在服务端允许的情况下;
- 支持发送和接收二进制数据;
- 新增formData对象,支持发送表单数据;
- 发送和获取数据时,可以获取进度信息;
- 可以设置请求的超时时间;
3. 使用
(1)请求头
设置 request header
- xhr提供了setRequestHeader来允许我们修改请求header。
获取 response header
xhr
提供了2个用来获取响应头部的方法:getAllResponseHeaders
和getResponseHeader
。- 前者是获取 response 中的所有header 字段,后者只是获取某个指定 header 字段的值。
(2)响应数据
指定xhr.respons类型
-
有些时候我们希望xhr.response 返回的就是我们想要的数据类型。比如:响应返回的数据是纯JSON字符串,但我们期望最终通过xhr.response 拿到的直接就是一个 js 对象,我们该怎么实现呢?
-
responseType 是xhr level 2 新增的属性,用来指定xhr.response 的数据类型
获取 response 数据
- xhr 提供了3个属性来获取请求返回的数据,分别是:xhr.response、xhr.responseText、xhr.responseXML
(3)其他
追踪ajax请求的当前状态
- 用xhr.readyState这个属性即可追踪到。这个属性是只读属性,总共有5种可能值,分别对应xhr不同的不同阶段。每次xhr.readyState的值发生变化时,都会触发xhr.onreadystatechange事件
设置请求的超时时间
- 如果请求过了很久还没有成功,为了不会白白占用的网络资源,我们一般会主动终止请求。XMLHttpRequest 提供了timeout 属性来允许设置请求的超时时间。
- 默认值:0,即不设置超时
获取上传、下载的进度
- 在上传或者下载比较大的文件时,实时显示当前的上传、下载进度是很普遍的产品需求。
- 我们可以通过
onprogress
事件来实时显示进度,默认情况下这个事件每50ms触发一次。 - 需要注意的是,上传过程和下载过程触发的是不同对象的
onprogress
事件。- 上传触发的是
xhr.upload
对象的onprogress
事件 - 下载触发的是
xhr
对象的onprogress
事件
- 上传触发的是
跨域携带cookie
- 在CORS 标准中做了规定,默认情况下,浏览器在发送跨域请求时,不能发送任何认证信息(cookies)
- 必须手动设置
xhr.withCredentials=true
4. 相关事件
(1)事件触发条件
onreadystatechange
- 每当
xhr.readyState
改变时触发
onloadstart
- 调用
xhr.send()
方法后立即触发
onprogress
xhr.upload.onprogress
在上传阶段(即xhr.send()之后,xhr.readystate=2
之前)触发,每50ms触发一次;xhr.onprogress
在下载阶段(即xhr.readystate=3
时)触发,每50ms触发一次。
onload
- 当请求成功完成时触发,此时
xhr.readystate = 4
onloadend
- 当请求结束(包括请求成功和请求失败)时触发
onabort
- 当调用
xhr.abort()
后触发
ontimeout:设置超时
xhr.timeout
不等于0,由请求开始即onloadstart
开始算起,当到达xhr.timeout
所设置时间请求还未结束即onloadend
,则触发此事件。
onerror:网络层级别的异常
- 上传还没有结束,则会先触发xhr.upload.onerror,再触发xhr.onerror;
- 若发生Network error时,上传已经结束,则只会触发xhr.onerror
(2)事件使用
发生abort/timeout/error异常的处理
- 中止请求:一旦发生
abort
或timeout
或error
异常,先立即中止当前请求 - 将
readystate
置为4
,并触发xhr.onreadystatechange
事件 - 如果上传阶段还没有结束,则依次触发以下事件:
xhr.upload.onprogress
xhr.upload.[onabort或ontimeout或onerror]
xhr.upload.onloadend
- 触发
xhr.onprogress
事件 - 触发
xhr.[onabort或ontimeout或onerror]
事件 - 触发
xhr.onloadend
事件
在哪个xhr事件中注册请求成功回调?
- 可以知道若xhr 请求成功,就会触发
xhr.onreadystatechange
和xhr.onload
两个事件。 - 因为
xhr.onreadystatechange
是每次xhr.readyState
变化时都会触发,而不是xhr.readyState=4
时才触发。所以选择xhr.onload
事件
xhr.onload = function () {
//如果请求成功
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//do successCallback
}
}