AJAX

Posted on Mar 31, 2020

AJAX——异步的JavaScript和XML,就是使用XMLHttpRequest对象与服务器通信。

发送http请求

var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function(){};
httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send();
  1. 创建XMLHttpRequest对象
  2. 告诉它
  3. 与哪个服务器交互
  4. 以哪种方法交互
  5. 给服务器的数据

open()方法

这个方法是选择互动的目标,比如玩游戏时,你要告诉服务器我要用这个账号玩,用微信要先选择一个人才能发消息。

由于[跨域问题][cors],open() 方法的 URL 参数默认*..不能..*使用第三方域名。
第一个参数如果不大写某些浏览器可能无法处理(比如FireFox,不知道哪些版本会有这个问题?)

send()方法

选择了目标后,就可以发消息了。发微信是说人类的语言,这个send方法就是说机器能听懂的语言。

指定发送给服务器的数据

send() 方法的参数就是要发送的数据,将会发送到服务器。像查询语句:"name=wss&age=66"
或者其他格式, 例如multipart/form-data,JSON,XML等。

指定返回数据的格式

服务区收到了我们的请求后,会给我们一个响应。我们要事先告诉服务器我们想要的数据的格式。

当以POST方式获取数据时,需要设置请求的MIME类型

用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件)

比如表单数据:httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

处理服务器响应

httpRequest.onreadystatechange函数负责处理响应,函数内应该怎么处理呢?

第一步:检查请求的状态。

请求的状态会经历如下变化:(每当状态变化是都会调用onreadystatechange方法?)

  • 0 (未初始化) or (请求还未初始化) UNSENT
  • 1 (正在加载) or (已建立服务器链接) OPENED
  • 2 (加载成功) or (请求已接受) HEADERS_RECEIVED
  • 3 (交互) or (正在处理请求) LOADING
  • 4 (完成) or (请求已完成并且响应已准备好) DONE

第二步:请求完成时,检查http状态码。

当请求完成,意味着完成了与服务器的交互。接下来就可以检查 HTTP状态码 了:

if (httpRequest.readyState === XMLHttpRequest.DONE) {
    // Everything is good, the response was received.
    if (httpRequest.status === 200) {
        // Perfect!
    } else {
        // There was a problem with the request.
        // For example, the response may have a 404 (Not Found)
        // or 500 (Internal Server Error) response code.
    }
} else {
    // Not ready yet.
}

在检查完HTTP响应码后,就可以使用服务器返回的数据了,有两个方法去访问这些数据:

  • httpRequest.responseText – 服务器以文本字符的形式返回
  • httpRequest.responseXML – 以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理 (返回JSON怎么处理?)

responseType属性

可以通过设置一个 XMLHttpRequest 对象的 responseType 属性来改变一个从服务器上返回的响应的数据类型
比如二进制数据:

httpRequest.open("GET", url, true);
httpRequest.responseType = "arraybuffer";
httpRequest.send();

监测进度

XMLHttpRequest 提供了各种在请求被处理期间发生的事件以供监听。包括定期进度通知、错误通知,等等。(这些事件与上面说的“请求状态readyState”有什么关系?)

var req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress, false);
req.addEventListener("load", transferComplete, false);
req.addEventListener("error", transferFailed, false);
req.addEventListener("abort", transferCanceled, false);
req.open();

// 如果 lengthComputable 属性的值是 false,那么意味着总字节数是未知并且 total 的值为零。
function updateProgress(evt) {
  if (evt.lengthComputable) {
    var percentComplete = evt.loaded / evt.total;
  } 
}

progress 事件同时存在于下载和上传的传输。上传相关事件在 XMLHttpRequest.upload 对象上被触发,像下面这样:

req.upload.addEventListener("progress", updateProgress);
req.upload.addEventListener("load", transferComplete);
req.upload.addEventListener("error", transferFailed);
req.upload.addEventListener("abort", transferCanceled);

使用 loadend 事件可以侦测到所有的三种加载结束条件(abort、load、error):

req.addEventListener("loadend", loadEnd, false);

参考

MDN AJAX Getting Started

使用JavaScript类型数组接受二进制数据