XMLHttpRequest对象的回顾与提高

最近在看Angular http模块的码源,发现对于基础的XMLHttpRequest对象还是认识不清楚,所以花了点时间整理一下,虽然现在已经很少直接使用XHR对象了,不过明白原理也能帮助理解http模块。

由于是在Angular环境下测试的,所以还是通过接口来说明XHR对象。

一、XHR的创建

  创建XHR对象实例就是实例化XMLHttpRequest对象

  const xhr = new XMLHttpRequest(); 二、启动请求以备发送      xhr.open(‘get‘, ‘http://localhost:3002/‘);   下面是typescript对于open方法的描述   

 1 /** 2  * Sets the request method, request URL, and synchronous flag. 3  * Throws a "SyntaxError" DOMException if either method is not a 4  * valid HTTP method or url cannot be parsed. 5  * Throws a "SecurityError" DOMException if method is a 6  * case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`. 7  * Throws an "InvalidAccessError" DOMException if async is false, current global object is a Window object, and the timeout attribute is not zero or the responseType attribute is not the empty string. 8 */ 9 open(method: string, url: string): void;10 open(method: string, url: string, async: boolean, username?: string | null, password?: string | null): void;

 

 三、发送请求

  xhr.send(null);   

1 /**2  * Initiates the request. The optional argument provides the request body. The argument is ignored if request method is GET or HEAD.3  * Throws an "InvalidStateError" DOMException if either state is not opened or the send() flag is set.4 */ 发起请求,注意如果request的method是GET或者HEAD,send方法的参数会被忽略。5 send(body?: Document | BodyInit | null): void;

 四、获得响应

  调用send方法之后,请求会被分派到服务器。服务器返回数据给客户端,客户端收到响应后,响应的数据会自动填充XHR对象的属性。相关的属性如下:

  1. responseText: 作为响应主体被返回的文本。
  2. responseXML:如果响应的内容类型是"text/xml"或者“application/xml”,这个属性中将保存包含响应数据的XML DOM文档。
  3. status:响应的HTTP状态。
  4. statusText:HTTP状态的说明

  在接收到响应后,第一步就是判断响应的状态status,一般情况下,可以把状态码200作为成功的标志,此时responseText已经被正确的赋值。另外,状态码304表示请求的资源没有被改变,可以直接使用浏览器中缓存的版本。

  同步通信的情况下,直接在send方法下面判断status是否等于200或者300,再做接下来的处理。

  

1 const xhr = new XMLHttpRequest();2 xhr.open(‘get‘, ‘http://localhost:3002/‘, false); // false 同步通信3 xhr.send(null);4 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {5  console.log(xhr.responseText);6 } else {7 console.log(‘unsuccessful‘ + xhr.status);8 }

   异步时不会阻塞下面的js代码的执行,如果还是使用上面的代码,就会得到unsuccessful0,即status状态码为0

  针对这种情况,XHR对象还提供了另外一个属性:readyState属性,该属性表示请求/响应过程的当前活动阶段。有如下可取值:

 /** * Returns client‘s state. */ readonly readyState: number;

 

  • 0:未初始化。还没有调用open()方法。
  • 1:启动。已经调用open()方法,但还没有调用send()方法。
  • 2:发送。已经调用send()方法,但还没有接收到响应。
  • 3:接收。已经接收到部分响应数据。
  • 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。

  只要readyState的值发生改变,就会触发readystatechange事件,所以我们可以在open()方法之前给XHR对象添加onreadystatechange事件,以应对异步通信的情况。

onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null;

 

 1 const xhr = new XMLHttpRequest(); 2 xhr.onreadystatechange = () => { 3 console.log(‘xhr.readystate: ‘ + xhr.readyState); // 1 2 3 4 4 if (xhr.readyState === 4) { 5 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { 6  console.log(xhr.responseText); 7 } else { 8 console.log(‘unsuccessful‘ + xhr.status); 9  }10  }11  };12 xhr.open(‘get‘, ‘http://localhost:3002/‘, true);13 xhr.send(null);

  可以在获取响应前取消异步请求,

  

 xhr.onreadystatechange = () => { console.log(‘xhr.readystate: ‘ + xhr.readyState); if (xhr.readyState === 2) {// 已经调用send()方法,但还没有接收到响应。 xhr.abort(); // 调用abort方法来取消异步请求 } if (xhr.readyState === 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { console.log(xhr.responseText); } else { console.log(‘unsuccessful‘ + xhr.status); } } };

 

 

五:总结

  上面是使用XHR对象的基本步骤,当然,还有很多细节的地方没有写到,接下来会分为多个文章进行记录。

 

相关文章