# XMLHttpRequest

> AJAX: Asynchronous JavaScript and XML\
> [MDN](https://developer.mozilla.org/en-US/docs/Web/API/XMLHTTPRequest)
>
> [doris](https://github.com/lcc19941214/doris) 自己封装的一个简单的XMLHttpRequest库

## 创建对象

XMLHttpRequest 是 AJAX 的基础。

### XMLHttpRequest 对象

所有现代浏览器均支持 XMLHttpRequest 对象（IE5 和 IE6 使用 ActiveXObject）。 XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下，对网页的某部分进行更新。

### 创建 XMLHttpRequest 对象

所有现代浏览器（IE7+、Firefox、Chrome、Safari 以及 Opera）均内建 XMLHttpRequest 对象。

#### 创建语法：

```javascript
variable = new XMLHttpRequest();
```

**老版本的 Internet Explorer （IE5 和 IE6）使用 ActiveX 对象：**

```javascript
variable = new ActiveXObject("Microsoft.XMLHTTP");
```

为了应对所有的现代浏览器，包括 IE5 和 IE6，请检查浏览器是否支持 XMLHttpRequest 对象。如果支持，则创建 XMLHttpRequest 对象。如果不支持，则创建 ActiveXObject ：

```javascript
var xmlhttp;
if (window.XMLHttpRequest) {
  // code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp = new XMLHttpRequest();
} else {
  // code for IE6, IE5
  xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
```

### 发送请求

#### 方法

**open**

`open(method, url, async)`

* method: "GET", "POST", "PUT", "DELETE", ...
* url: "url"
* async: true | false

**GET**

* GET可以得到缓存结果
* GET的长度是有限的（2048）
* GET不够保密
* 编码类型（ASIIC）

```javascript
XHR.open( "GET" , "URL" , true );
XHR.send();

XHR.open( "GET" , "URL?name=value&name=value" , true );
XHR.send();
```

**POST**

* 不会得到缓存结果
* 可以发送大量数据
* 足够安全
* 编码类型（无限制，可包括二进制流）

```javascript
XHR.open( "POST" , "URL" , true );
XHR.send();

XHR.oepn( "POST" , "URL" , true );
XHR.setRequestHeader(header , value);
XHR.send("name&value"); // request body
```

**async**

* 异步时，不用等待服务器返回信息即可继续执行其他操作。需要设置服务器返回的信息为对应的状态时，应当执行的操作（`onreadystatechange`）

```javascript
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState==4 && xmlhttp.status==200) {
    document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
  }
}
```

* 同步时，需要等待服务器返回信息才能继续执行后面的脚本。**设置为同步时**，主线程会顺序执行xhr对象后面的语句，**无法侦听readystatechange事件**。

**send**

`send(body)`

**body**

* A Document, in which case it is serialized before being sent.
* A BodyInit, which as per the Fetch spec can be a Blob, BufferSource, FormData, URLSearchParams, ReadableStream, or USVString object.

**note**

* 使用`POST`时，需要设置`Content-Type`为`application/x-www-form-urlencoded`
* 如果send方法传入的不是字符串，则不需要设置header的`Content-Type`

### Properties

* responseText 获得字符串形式的响应数据
* responseXML 获得字符串形式的响应数据
* getResponseHeader 获取响应头，没有或不存在则返回null
* getAllResponseHeaders
* readystate
  * `onreadystatechange` 每次readystate发生改变时，即触发该事件
  * 取值
    * 0: 请求初始化，还没调用open()方法
    * 1: 服务器建立连接，还没调用send()方法
    * 2: 请求已经接受，已经调用send()方法,响应头和响应状态已经返回
    * 3: 请求处理中，下载中,已经得到部分响应实体
    * 4: 请求完成，响应就绪
* status
* statusText

### XHR 2.0

* 支持设置`timeout`

```javascript
xhr.timeout = 2000; // time in milliseconds

xhr.onload = function () { // Request finished. Do processing here. };

xhr.ontimeout = function (e) { // XMLHttpRequest timed out. Do something here. };
```

* 支持使用`FormData`
* 支持CORS，需要后端配合。
  * `withCredentials`

```javascript
xhr.withCredentials = true;
```

* 可配置`responseType` - an enumerated value that returns the type of response
  * text
  * json
  * arrayBuffer
  * document


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://coolconan.gitbook.io/roadmap/front-end/web-standard/javascript/ajax/180720-xmlhttprequest.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
