发送 Ajax 请求
发送一个 Ajax 请求,主要分为四个步骤:
创建一个 XHR 实例对象
开启请求
对响应进行监听
发送请求
1. 创建 XHR 实例对象
创建一个 XMLHttpRequest 实例对象
var request = new XMLHttpRequest();
2. 开启请求
语法:open([method],[url],[async], [username], [userpass])
method
get/delete/head/options
post/put/trace/connect
url:请求的 API 接口地址
async:控制同步异步,默认为 true,为异步,真实项目中都是使用异步,防止阻塞后续代码的执行
username、userpass:用户名和密码,这两个参数一般不用
xhr.open('get','url', true)
3. 监听请求
监听请求要放在发送请求之前
使用 XHR 对象的 onreadystatechange 事件监听响应过程:
xhr.onreadystatechange = function(){
if (!/^(2|3)\d{2}$/.test(xhr.status)) return;
//=> 否则,HTTP 请求成功,证明返回了数据
if(xhr.readyState === 2){
//=> 响应头信息已经获取到
// 获取的格林尼治时间,而且是字符串
let time = xhr.getResponseHeader('date');
new Date(time);
// new Date() 获取当前客户端时间
// new Date(时间字符串) 把指定的时间字符串格式化为标准的北京时间(返回的不是字符串,而是 Date 的实例)
}
if (xhr.readtState === 4) {
//=> 响应主体已经能够获取到
console.log(xhr.responseText);
}
}
判断是否请求成功,需要两个状态码 readyState
和 status
readyState === 4
表示请求完成,已经响应status === 200
表示请求成功,服务器端正确响应,获取到数据实际上
status
只要是以 2 开头或者 3 开头 ,都表示成功
获取响应数据(都是 XHR 对象的属性):
responseText
:获取字符串形式的响应数据(重要)responseXML
:获取 XML 形式的响应数据,现在几乎都是使用 JSON格式
staus
和 statusText
:以数字或者文本形式返回 HTTP 状态码
2:代表成功
3:网页重定向
4:资源请求错误
5:一般是服务器端错误
4. 发送请求
通过 XHR 对象的 send(string)
发送请求到服务器
get 请求如果也发送了数据,那么在 network 中是没有的,也就是不会起作用的
xhr.send();
xhr.send('q=1&w=2');
如果 Ajax 是同步的,后续代码不会执行,要等到 Ajax 状态成功后才会执行,异步则不会这样。
XHR 实例的其他属性和方法
1. readyState 状态码
当请求发送出去时
- 如果是同步的过程,整个 JS 代码不再往下执行,等待请求成功,当成功后再执行 JS 代码,这时的
readyState
已经变成 4 ,不会监听到 2、3 的变化
- 如果是异步的过程,那么就会监听到 2、3 的变化
readyState
:在响应返回成功的时候得到通知,需要监听 readyState
属性的变化,这个属性的变化代表着服务器响应的变化。
0:请求还未初始化,XHR 刚创建实例的时候,open 还没有调用
1:服务器连接已建立,open 已经调用了
2:请求已接收,也就是接收到头信息了
3:请求处理中,也就是接收到响应主体了
4:请求已完成,且响应已就绪,也就是响应完成了
2. 设置请求头
setRequestHeader(key, value)
,设置请求头信息,必须写在 open
和 send
之间
自定义信息:
xhr.setRequestHeader("name", "aa");
设置 content-type:
目前通过 POST 传递参数的时候,后台接受的是字符串,需要转换成 key value 形式,只需要将 Content-Type 设置为 application/x-www-form-urlencoded
,这样后台接受到的参数就是 format data
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
注意不能设置中文。
需要我们把中文转为计算机支持的字符:
var str = escape('中国');
str = unescape('%u4E2D%u56FD');
var str = encodeURI('中国');
str = decodeURI('%E4%B8%AD%E5%9B%BD');
//=> 下面这个方式更加全面,能够把一些特殊的字符也进行转义
var str = encodeURIComponent('中国');
3. 获取请求头
getAllResponseHeader()
:获取所有的响应报头
getResponseHeader(key)
:获取 key 对应的响应头信息
xhr.getResponseHeader('date'); //=> 获取服务器响应时间
4. 获取响应主体
response
:获取响应主体
responseText
:响应主体的字符串形式(重要)
responseType
:响应类型
responseURL
:响应的地址,也就是请求地址
responseXML
:响应主体的 XML 文档形式
5. HTTP 状态码
status
:返回 HTTP 状态码
statusText
:状态码的描述
6. 设置请求超时时间
timeout
:设置超时时间
xhr.timeout = 3000;
xhr.ontimeout = () => {
console.log('请求超时');
}
7. 是否允许跨域
withCredentials
:是否允许携带 cookie 等信息跨域传输,默认 false
8. 强制中断请求
abort()
:强制中断 Ajax 请求
setTimeout(() => {
xhr.abort();
},1000);
xhr.onabort = () => {
console.log('请求被强制中断');
}
9. 进度信息
传送数据的时候,有一个 progress 事件,用来返回进度信息。
它分成上传和下载两种情况。下载的 progress 事件属于xhr 对象,上传的 progress 事件属于 xhr.upload 对象。
xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
然后,在回调函数里面,使用这个事件的一些属性。
function updateProgress(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
}
}
event.total 是需要传输的总字节,event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于 0。
与progress事件相关的,还有其他五个事件,可以分别指定回调函数:
- load事件:传输成功完成。
- abort事件:传输被用户取消。
- error事件:传输中出现错误。
- loadstart事件:传输开始。
- loadEnd事件:传输结束,但是不知道成功还是失败。