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;

 method的可以选择的值: delete |get |head |jsonp |options |post |put |patch

 三、发送请求

  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或者304,再做接下来的处理。

  

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对象的基本步骤,当然,还有很多细节的地方没有写到,接下来会分为多个文章进行记录。

 修改:

  • 2019-02-16 18:15:56添加几种请求方式
posted on 2019-02-08 23:07  西门本不吹雪  阅读(575)  评论(0编辑  收藏  举报