XMLHttpRequest对象的回顾与提高
最近在看Angular http模块的码源,发现对于基础的XMLHttpRequest对象还是认识不清楚,所以花了点时间整理一下,虽然现在已经很少直接使用XHR对象了,不过明白原理也能帮助理解http模块。
由于是在Angular环境下测试的,所以还是通过接口来说明XHR对象。
一、XHR的创建
创建XHR对象实例就是实例化XMLHttpRequest对象
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
三、发送请求
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对象的属性。相关的属性如下:
- responseText: 作为响应主体被返回的文本。
- responseXML:如果响应的内容类型是"text/xml"或者“application/xml”,这个属性中将保存包含响应数据的XML DOM文档。
- status:响应的HTTP状态。
- 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添加几种请求方式