理解AJAX

58次阅读

共计 3604 个字符,预计需要花费 10 分钟才能阅读完成。

先参考 MDN 的什么是 AJAX

AJAX 是异步的 JavaScript 和 XML(Asynchronous JavaScript And XML)。简单点说,就是使用 XMLHttpRequest 对象与服务器通信。它可以使用 JSON,XML,HTML 和 text 文本等格式发送和接收数据。AJAX 最吸引人的就是它的“异步”特性,也就是说他可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。
使用 AJAX 的两个特性

在不重新加载页面的情况下发送请求给服务器。
接受并使用从服务器发来的数据。

AJAX 请求过程是什么样的
先看代码
function request(){
let httpRequest = new XMLHttpRequest();
// 要在函数闭包内创建 XHR 变量,避免被其他 request 相互覆盖;
if(!httpRequest){
alert(‘Giving up :( Cannot create an XMLHTTP instance’);
return false;
}

httpRequest.onreadystatechange = alertContents;
httpRequest.open(‘GET’, ‘test.html’);
httpRequest.send();
}

function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert(‘There was a problem with the request.’);
}
}
}
创建 XMLHttpRequest 对象
let httpRequest = new XMLHttpRequest();
什么是 onreadystatechange
只要 readyState 属性发生变化,就会调用相应的处理函数。
在这个例子中,处理函数为 alertContents。要注意的是,函数名后没有参数,因为你把一个引用赋值给了函数,而不是真正的调用了它。下面会讲关于这个处理函数的具体实现。
还有 onload()
onreadystatechange 顾名思义,每次 state 变化的时候都会调用被给的函数,如果只想在状态为完成的时候被调用,可以使用 onload 来代替。
open() 初始化

不管 get 还是 post,都要先 open()。
第一个参数是 HTTP 请求方法 – 有 GET,POST,HEAD 以及服务器支持的其他方法。保证这些方法一定要是大写字母,否则其他一些浏览器(比如 FireFox)可能无法处理这个请求。
第二个参数是你要发送的 URL。由于安全原因,默认不能调用第三方 URL 域名。确保你在页面中使用的是正确的域名,否则在调用 open() 方法是会有“权限被拒绝”错误提示。一个容易犯的错误是你企图通过 domain.tld 访问网站,而不是使用 www.domain.tld。
第三个参数是可选的,用于设置请求是否是异步的。如果设为 true (默认设置),JavaScript 执行会持续,并且在服务器还没有响应的情况下与页面进行交互。

send() 发送
上面的就是一个 get 情景中,用 send() 的例子
再提供一个 post 例子
post 要设定相应的 request header,调用 setRequestHeader()
var xhr = new XMLHttpRequest();
xhr.open(“POST”, ‘/server’, true);

// 如果要 post 就要设定相应的 request header
xhr.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);

xhr.onreadystatechange = function() { // 这里定义 onreadystatechange 前面已经讲过了
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
// 请求完毕,做一些处理
}
}
xhr.send(“foo=bar&lorem=ipsum”);// 正式发送的 send() 调用

处理 onreadystatechange 的函数实现
我们知道会把一个函数赋予 xhr.onreadystatechange。那么这个函数应该做什么?

首先,函数要检查请求的状态。如果状态的值是 XMLHttpRequest.DONE(对应的值是 4),意味着服务器响应收到了并且是没问题的,然后就可以继续执行。
if (httpRequest.readyState === XMLHttpRequest.DONE) {

} else {

}
readyState 对应值

0 UNSENT 还没 open()
1 OPENED 已经 open() 了
2 HEADERS_RECEIVED 已经 send() 了
3 LOADING 获取返回数据中
4 DONE 完成

接下来,检查 HTTP 响应的 response code。可能的响应码都已经列在表中 W3C 响应码列表。在下面的例子中,我们通过检查响应码 200 OK 区别对待成功和不成功的 AJAX 调用。
if (httpRequest.status === 200) {

} else {

}
粗略的响应码解释

2XX 成功
3XX 重新导向
4XX 请求有问题
5XX 服务端有问题

一切检查后,那么怎么获取返回数据?

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

那么经常看到的 jquery 中的 ajax 是什么样的?
我们平常用 jquery 的 ajax 都是传一个对象,来具体自己想做什么样的请求。那么实现 ajax 的时候,也是先要从这传进来的一个对象里面找参数。处理完了以后就用这些得到的参数去做请求就可以了。
粗略的实现
function ajax(options){
if(window.XMLHttpRequest){
let xhr = new XMLHttpRequest;
}else{
let xhr = new ActiveXObject();//IE6 and oler
}

// 从 option 获取一些参数
let method = options.type || ‘GET’;
let dataType = options.dataType || ‘application/x-www-form-urlencoded’;
let params = options.data;
let success = options.success;
let fail = option.fail;

// 设置 onreadystatechange
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
//call success
}else{
//call fail
}
}

// 正式进行请求
if(method == ‘GET){
xhr.open(‘GET’,url + ‘?’ + params,true);
xhr.send();
}else if(method == ‘POST’){
xhr.open(‘POST’,url, true);
xhr.setRequestHeader(‘Content-Type’, dataType);
xhr.send(params);
}else{
…other method handler
}
}
当然还可以 fetch
Fetch 是浏览器提供的原生 AJAX 接口。这里不做过多介绍。
要重点提到的就是 fetch 请求返回的是一个 Promise,所以对获取数据处理要用 then()。
一些例子
fetch(‘/data.json’)
.then(res => {
res.text() // response body (=> 还是返回 Promise,需要再 then())
res.json() // parse via JSON (=> 还是返回 Promise,需要再 then())
res.status //=> 200
res.statusText //=> ‘OK’
res.redirected //=> false
res.ok //=> true
res.url //=> ‘http://site.com/data.json’
res.type //=> ‘basic’
// (‘cors’ ‘default’ ‘error’
// ‘opaque’ ‘opaqueredirect’)

res.headers.get(‘Content-Type’)
})
参考信息
MDN 什么是 AJAX?MDN XMLHttpRequest 阮一峰 ES6 指南 Promise 对象 fetch cheatsheet

正文完
 0