XMLHttpRequest 的实例方法

XMLHttpRequest.open()

XMLHttpRequest.open()方法用于指定 HTTP 请求的参数,或者说初始化 XMLHttpRequest 实例对象。它一共可以接受五个参数。

  1. void open(
  2. string method,
  3. string url,
  4. optional boolean async,
  5. optional string user,
  6. optional string password
  7. );
  • method:表示 HTTP 动词方法,比如GETPOSTPUTDELETEHEAD等。
  • url: 表示请求发送目标 URL。
  • async: 布尔值,表示请求是否为异步,默认为true。如果设为false,则send()方法只有等到收到服务器返回了结果,才会进行下一步操作。该参数可选。由于同步 AJAX 请求会造成浏览器失去响应,许多浏览器已经禁止在主线程使用,只允许 Worker 里面使用。所以,这个参数轻易不应该设为false
  • user:表示用于认证的用户名,默认为空字符串。该参数可选。
  • password:表示用于认证的密码,默认为空字符串。该参数可选。

注意,如果对使用过open()方法的 AJAX 请求,再次使用这个方法,等同于调用abort(),即终止请求。

下面发送 POST 请求的例子。

  1. var xhr = new XMLHttpRequest();
  2. xhr.open('POST', encodeURI('someURL'));

XMLHttpRequest.send()

XMLHttpRequest.send()方法用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只有一个 URL,没有数据体,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。

下面是 GET 请求的例子。

  1. var xhr = new XMLHttpRequest();
  2. xhr.open('GET',
  3. 'http://www.example.com/?id=' + encodeURIComponent(id),
  4. true
  5. );
  6. xhr.send(null);

上面代码中,GET请求的参数,作为查询字符串附加在 URL 后面。

下面是发送 POST 请求的例子。

  1. var xhr = new XMLHttpRequest();
  2. var data = 'email='
  3. + encodeURIComponent(email)
  4. + '&password='
  5. + encodeURIComponent(password);
  6. xhr.open('POST', 'http://www.example.com', true);
  7. xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  8. xhr.send(data);

注意,所有 XMLHttpRequest 的监听事件,都必须在send()方法调用之前设定。

send方法的参数就是发送的数据。多种格式的数据,都可以作为它的参数。

  1. void send();
  2. void send(ArrayBufferView data);
  3. void send(Blob data);
  4. void send(Document data);
  5. void send(String data);
  6. void send(FormData data);

如果send()发送 DOM 对象,在发送之前,数据会先被串行化。如果发送二进制数据,最好是发送ArrayBufferViewBlob对象,这使得通过 Ajax 上传文件成为可能。

下面是发送表单数据的例子。FormData对象可以用于构造表单数据。

  1. var formData = new FormData();
  2. formData.append('username', '张三');
  3. formData.append('email', 'zhangsan@example.com');
  4. formData.append('birthDate', 1940);
  5. var xhr = new XMLHttpRequest();
  6. xhr.open('POST', '/register');
  7. xhr.send(formData);

上面代码中,FormData对象构造了表单数据,然后使用send()方法发送。它的效果与发送下面的表单数据是一样的。

  1. <form id='registration' name='registration' action='/register'>
  2. <input type='text' name='username' value='张三'>
  3. <input type='email' name='email' value='zhangsan@example.com'>
  4. <input type='number' name='birthDate' value='1940'>
  5. <input type='submit' onclick='return sendForm(this.form);'>
  6. </form>

下面的例子是使用FormData对象加工表单数据,然后再发送。

  1. function sendForm(form) {
  2. var formData = new FormData(form);
  3. formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');
  4. var xhr = new XMLHttpRequest();
  5. xhr.open('POST', form.action, true);
  6. xhr.onload = function() {
  7. // ...
  8. };
  9. xhr.send(formData);
  10. return false;
  11. }
  12. var form = document.querySelector('#registration');
  13. sendForm(form);

XMLHttpRequest.setRequestHeader()

XMLHttpRequest.setRequestHeader()方法用于设置浏览器发送的 HTTP 请求的头信息。该方法必须在open()之后、send()之前调用。如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。

该方法接受两个参数。第一个参数是字符串,表示头信息的字段名,第二个参数是字段值。

  1. xhr.setRequestHeader('Content-Type', 'application/json');
  2. xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
  3. xhr.send(JSON.stringify(data));

上面代码首先设置头信息Content-Type,表示发送 JSON 格式的数据;然后设置Content-Length,表示数据长度;最后发送 JSON 数据。

XMLHttpRequest.overrideMimeType()

XMLHttpRequest.overrideMimeType()方法用来指定 MIME 类型,覆盖服务器返回的真正的 MIME 类型,从而让浏览器进行不一样的处理。举例来说,服务器返回的数据类型是text/xml,由于种种原因浏览器解析不成功报错,这时就拿不到数据了。为了拿到原始数据,我们可以把 MIME 类型改成text/plain,这样浏览器就不会去自动解析,从而我们就可以拿到原始文本了。

  1. xhr.overrideMimeType('text/plain')

注意,该方法必须在send()方法之前调用。

修改服务器返回的数据类型,不是正常情况下应该采取的方法。如果希望服务器返回指定的数据类型,可以用responseType属性告诉服务器,就像下面的例子。只有在服务器无法返回某种数据类型时,才使用overrideMimeType()方法。

  1. var xhr = new XMLHttpRequest();
  2. xhr.onload = function(e) {
  3. var arraybuffer = xhr.response;
  4. // ...
  5. }
  6. xhr.open('GET', url);
  7. xhr.responseType = 'arraybuffer';
  8. xhr.send();

XMLHttpRequest.getResponseHeader()

XMLHttpRequest.getResponseHeader()方法返回 HTTP 头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,返回null。该方法的参数不区分大小写。

  1. function getHeaderTime() {
  2. console.log(this.getResponseHeader("Last-Modified"));
  3. }
  4. var xhr = new XMLHttpRequest();
  5. xhr.open('HEAD', 'yourpage.html');
  6. xhr.onload = getHeaderTime;
  7. xhr.send();

如果有多个字段同名,它们的值会被连接为一个字符串,每个字段之间使用“逗号+空格”分隔。

XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.getAllResponseHeaders()方法返回一个字符串,表示服务器发来的所有 HTTP 头信息。格式为字符串,每个头信息之间使用CRLF分隔(回车+换行),如果没有收到服务器回应,该属性为null。如果发生网络错误,该属性为空字符串。

  1. var xhr = new XMLHttpRequest();
  2. xhr.open('GET', 'foo.txt', true);
  3. xhr.send();
  4. xhr.onreadystatechange = function () {
  5. if (this.readyState === 4) {
  6. var headers = xhr.getAllResponseHeaders();
  7. }
  8. }

上面代码用于获取服务器返回的所有头信息。它可能是下面这样的字符串。

  1. date: Fri, 08 Dec 2017 21:04:30 GMT\r\n
  2. content-encoding: gzip\r\n
  3. x-content-type-options: nosniff\r\n
  4. server: meinheld/0.6.1\r\n
  5. x-frame-options: DENY\r\n
  6. content-type: text/html; charset=utf-8\r\n
  7. connection: keep-alive\r\n
  8. strict-transport-security: max-age=63072000\r\n
  9. vary: Cookie, Accept-Encoding\r\n
  10. content-length: 6502\r\n
  11. x-xss-protection: 1; mode=block\r\n

然后,对这个字符串进行处理。

  1. var arr = headers.trim().split(/[\r\n]+/);
  2. var headerMap = {};
  3. arr.forEach(function (line) {
  4. var parts = line.split(': ');
  5. var header = parts.shift();
  6. var value = parts.join(': ');
  7. headerMap[header] = value;
  8. });
  9. headerMap['content-length'] // "6502"

XMLHttpRequest.abort()

XMLHttpRequest.abort()方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState属性变为4status属性变为0

  1. var xhr = new XMLHttpRequest();
  2. xhr.open('GET', 'http://www.example.com/page.php', true);
  3. setTimeout(function () {
  4. if (xhr) {
  5. xhr.abort();
  6. xhr = null;
  7. }
  8. }, 5000);

上面代码在发出5秒之后,终止一个 AJAX 请求。