发送 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事件:传输结束,但是不知道成功还是失败。
