一、什么是Ajax?
Ajax全称为“Asynchronous JavaScript and XML”(异步JavaScript和XML),是一种创建交互式网页应用的网页开发技术。
二、Ajax的工作原理
Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给 Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
三、Ajax的请求步骤
四、XMLHttpRequest对象的属性、方法和事件
readyState
[只读属性]用于追踪 xhr
当前的状态,共有 5 种可能的值,分别对应 xhr
不同的阶段。
每次 readyState
值变化时,都会触发 xhr.onreadystatechange
事件。
-
responseText
- 默认值为空字符串
""
- 只有当
responseType
为text
、""
时,xhr
对象上才有此属性,此时才能调用xhr.responseText
,否则抛错。 - 只有当请求成功时,才能拿到正确值。以下
2
种情况下值都为空字符串""
:请求未完成、请求失败。
- 默认值为空字符串
-
responseXML
- 默认值为
null
- 只有当
responseType
为text
、""
、document
时,xhr
对象上才有此属性,此时才能调用xhr.responseXML
,否则抛错。 - 只有当请求成功且返回数据被正确解析时,才能拿到正确值。以下
3
种情况下值都为null
:请求未完成、请求失败、请求成功但返回数据无法被正确解析时。
- 默认值为
status
和statusText
status
属性表示 HTTP
响应状态码,如 200
、302
、400
等。 statusText
属性表示 HTTP
响应状态的描述文本,如 OK
、Not Found
等。
注意:在 xhr.onload
事件中,不能简单的判断 xhr.status === 200
,因为 20x
、304
等 HTTP
状态码也被认为是请求成功。
responseType
和response
可在 xhr.send()
前设置 responseType
,用于指定返回的响应数据类型。 和 xhr.overrideMimeType()
方法效果相同,推荐使用 responseType
。
-
open
- 用于创建
HTTP
请求,但请求并未发送。 method
, 请求类型,如GET
、POST
等,大小写不敏感。url
,URL
地址-
async
, 是否异步,默认true
。
若为同步请求时xhr.timeout
值必须为 0。xhr.withCredentials
值必须为 false。xhr.responseType
值必须为""
,(text
也不允许)。
- 用于创建
-
send
-
定义
HTTP
请求的数据(body
),当method
为GET
、HEAD
时,该参数忽略。body
可为ArrayBuffer
、Blob、Document
(类似XML
格式数据)、DOMString
(字符串)、FormData
(表单)。
ArrayBuffer、Blob、Document、DOMString、Formdata 详细参考。
注意:body 参数会影响请求头部的content-type
默认值。- 如果
data
是Document
类型,同时也是HTML Document
类型,则content-type
默认值为text/html;charset=UTF-8
;否则为application/xml
;charset=UTF-8; - 如果
data
是DOMString
类型,content-type
默认值为text/plain;charset=UTF-8
; - 如果
data
是FormData
类型,content-type
默认值为multipart/form-data; boundary=[xxx]
- 如果
data
是其他类型,则不会设置content-type
的默认
- 如果
-
setRequestHeader
设置请求 HTTP 请求头信息。如content-type
、cookie
、accept-xxx
等。
header 参数大小写不敏感。
必须在open()
方法后,send()
方法前调用,否则会抛错。
可调用多次,最终值不会覆盖,而是采用追加append
方式。
-
getResponseHeader
- 获取某个指定 header 字段的值。
- header 字段不区分大小写。
- 有严格安全限制,详见
getAllResponseHeaders
方法。
-
getAllResponseHeaders()
- 获取 response 中所有 header 字段。
-
有严格安全限制。如下:
- 无论跨域或同域请求,无法获取
Set-Cookie
、Set-Cookie2
字段值。 -
跨域请求,只可获取simple response header和Access-Control-Expose-Headers(名词解释见下方),否则会报错:
Refused to get unsafe header
。故若想访问其他字段,需后端添加到Access-Control-Expose-Headers
中。
- 无论跨域或同域请求,无法获取
事件触发条件
事件 | 触发条件 |
---|---|
onreadystatechange | 每当xhr.readyState 改变时触发;但xhr.readyState 由非 0 值变为 0 时不触发。 |
onloadstart | 调用xhr.send() 方法后立即触发,若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 | 在请求过程中,若发生 Network error 则会触发此事件(若发生 Network error 时,上传还没有结束,则会先触发 xhr.upload.onerror ,再触发 xhr.onerror ;若发生 Network error 时,上传已经结束,则只会触发xhr.onerror )。注意,只有发生了网络层级别的异常才会触发此事件,对于应用层级别的异常,如响应返回的xhr.statusCode 是 4xx 时,并不属于 Network error ,所以不会触发 onerror 事件,而是会触发 onload 事件。 |
五、下面以JSONPlaceHolder为数据服务,编写案例,以进一步阐述Ajax及XMLHttpRequest对象的用法
JSONPlaceholder 附带一组 6 种通用资源:
/posts | 100 posts |
/comments | 500 comments |
/albums | 100 albums |
/photos | 5000 photos |
/todos | 200 todos |
/users | 10 users |
-
使用Ajax实现异步请求
//一般实现
const xhr = new XMLHttpRequest();
xhr.open('get', '/server', true);
//设置响应类型
xhr.responseType = 'json'
//设置请求头信息
xhr.setRequestHeader('MyHeader', 'MyValue');
//设置请求失败监听函数
xhr.onload = function () {
console.log('请求失败了...')
}
//为XMLHttpRequest对象的状态设置监听事件(监听onreadystatechange)
xhr.onreadystatechange = function () {
if (this.readyState !== 4) {
return;
}
if (this.status >= 200 && this.status < 300) {
//响应正常
console.log(this.responseText)
} else {
console.log(this.statusText)
}
}
//发送请求
xhr.send(null);