发送 Ajax 请求

发送一个 Ajax 请求,主要分为四个步骤

  • 创建一个 XHR 实例对象

  • 开启请求

  • 对响应进行监听

  • 发送请求

1. 创建 XHR 实例对象

创建一个 XMLHttpRequest 实例对象

  1. 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:用户名和密码,这两个参数一般不用

  1. xhr.open('get','url', true)

3. 监听请求

监听请求要放在发送请求之前

使用 XHR 对象的 onreadystatechange 事件监听响应过程:

  1. xhr.onreadystatechange = function(){
  2. if (!/^(2|3)\d{2}$/.test(xhr.status)) return;
  3. //=> 否则,HTTP 请求成功,证明返回了数据
  4. if(xhr.readyState === 2){
  5. //=> 响应头信息已经获取到
  6. // 获取的格林尼治时间,而且是字符串
  7. let time = xhr.getResponseHeader('date');
  8. new Date(time);
  9. // new Date() 获取当前客户端时间
  10. // new Date(时间字符串) 把指定的时间字符串格式化为标准的北京时间(返回的不是字符串,而是 Date 的实例)
  11. }
  12. if (xhr.readtState === 4) {
  13. //=> 响应主体已经能够获取到
  14. console.log(xhr.responseText);
  15. }
  16. }

判断是否请求成功,需要两个状态码 readyStatestatus

  • readyState === 4 表示请求完成,已经响应

  • status === 200 表示请求成功,服务器端正确响应,获取到数据

  • 实际上 status 只要是以 2 开头或者 3 开头 ,都表示成功

获取响应数据(都是 XHR 对象的属性):

  • responseText:获取字符串形式的响应数据(重要)

  • responseXML:获取 XML 形式的响应数据,现在几乎都是使用 JSON格式

stausstatusText:以数字或者文本形式返回 HTTP 状态码

  • 2:代表成功

  • 3:网页重定向

  • 4:资源请求错误

  • 5:一般是服务器端错误

4. 发送请求

通过 XHR 对象的 send(string) 发送请求到服务器

get 请求如果也发送了数据,那么在 network 中是没有的,也就是不会起作用的

  1. xhr.send();
  2. 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),设置请求头信息,必须写在 opensend 之间

自定义信息:

  1. xhr.setRequestHeader("name", "aa");

设置 content-type:

目前通过 POST 传递参数的时候,后台接受的是字符串,需要转换成 key value 形式,只需要将 Content-Type 设置为 application/x-www-form-urlencoded,这样后台接受到的参数就是 format data

  1. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

注意不能设置中文。

需要我们把中文转为计算机支持的字符:

  1. var str = escape('中国');
  2. str = unescape('%u4E2D%u56FD');
  3. var str = encodeURI('中国');
  4. str = decodeURI('%E4%B8%AD%E5%9B%BD');
  5. //=> 下面这个方式更加全面,能够把一些特殊的字符也进行转义
  6. var str = encodeURIComponent('中国');

3. 获取请求头

getAllResponseHeader():获取所有的响应报头

getResponseHeader(key):获取 key 对应的响应头信息

  1. xhr.getResponseHeader('date'); //=> 获取服务器响应时间

4. 获取响应主体

response:获取响应主体

responseText:响应主体的字符串形式(重要)

responseType:响应类型

responseURL:响应的地址,也就是请求地址

responseXML:响应主体的 XML 文档形式

5. HTTP 状态码

status:返回 HTTP 状态码

statusText:状态码的描述

6. 设置请求超时时间

timeout:设置超时时间

  1. xhr.timeout = 3000;
  2. xhr.ontimeout = () => {
  3. console.log('请求超时');
  4. }

7. 是否允许跨域

withCredentials:是否允许携带 cookie 等信息跨域传输,默认 false

8. 强制中断请求

abort():强制中断 Ajax 请求

  1. setTimeout(() => {
  2. xhr.abort();
  3. },1000);
  4. xhr.onabort = () => {
  5. console.log('请求被强制中断');
  6. }

9. 进度信息

传送数据的时候,有一个 progress 事件,用来返回进度信息。

它分成上传和下载两种情况。下载的 progress 事件属于xhr 对象,上传的 progress 事件属于 xhr.upload 对象。

  1. xhr.onprogress = updateProgress;
  2. xhr.upload.onprogress = updateProgress;

然后,在回调函数里面,使用这个事件的一些属性。

  1. function updateProgress(event) {
  2. if (event.lengthComputable) {
  3. var percentComplete = event.loaded / event.total;
  4. }
  5. }

event.total 是需要传输的总字节,event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于 0。

与progress事件相关的,还有其他五个事件,可以分别指定回调函数:

  • load事件:传输成功完成。
  • abort事件:传输被用户取消。
  • error事件:传输中出现错误。
  • loadstart事件:传输开始。
  • loadEnd事件:传输结束,但是不知道成功还是失败。