Ajax 发送请求
交互过程中,发送请求是第一步。那么,我们将如何构造请求呢?
这一章节,我们将一步一步来构建 Ajax 请求。学习本节,你将学会:
如何通过 XMLHttpRequest 和 ActiveXObject 来构造通用的 xhr 对象。
如何通过 xhr 对象来发送 GET、 POST 等请求。
Content-type 在 Ajax 数据发送中的作用。
那么,接下来让我们进入本节的学习吧。
首先,我们需要构造 xhr 对象。具体就是通过 new 来实例化 XMLHttpRequest 实例。
const xhr = new XMLHttpRequest();
问题来了,我们知道早期浏览器如 IE5、IE6 并没有直接 XMLHttpRequest,如果我们直接使用 XMLHttpRequest 构造,很大可能在早期浏览器我们会得到未定义的报错。因此,我们需要通过一定兼容性的写法来这个问题。
var xhr;
if (window.XMLHttpRequest) {
// 如果存在 XMLHttpRequest,就直接使用 XMLHttpRequest
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// IE
// 如果不存在 XMLHttpRequest,但存在 ActiveXObject,则考虑 ActiveXObject 的情况
// XMLHttp 版本
var versions = [
"Msxml2.XMLHttp.5.0",
"Msxml2.XMLHttp.4.0",
"Msxml2.XMLHttp.3.0",
"Msxml2.XMLHttp",
"Microsoft.XMLHttp"
];
// 通过 for 循环尝试某个 XMLHttp 版本的 ActiveXObject 实例
// try...catch.. 捕获并消化掉 ActiveXObject 实例化失败的
try {
for (var i = ; i < versions.length; i++) {
xhr = new ActiveXObject(versions[i]);
break;
}
} catch (error) {}
}
if (!xhr) {
alert("当前环境初始化Ajax对象");
}
ActiveXObject 属于微软的私有拓展对象,只有在 IE 上才会有。该对象只能用于实例化化对象。 在我们上面的实现中,实例化 ActiveXObject 我们会传入参数 Msxml2.XMLHTTP
或者 Microsoft.XMLHTTP
等,该参数代表着提供对象的应用程序的。
其中,Msxml2.XMLHttp.5.0
、Msxml2.XMLHttp.4.0
、Msxml2.XMLHttp.3.0
、Msxml2.XMLHttp
和 Microsoft.XMLHttp
分别代表着 XMLHttp 的高低版本。我们通过 for 循环,在采用正常有效版本的时候跳出循环。同时,使用 try…catch… 来捕获消化情况下的报错。
当然,我们也可以包装我们的 xhr 对象,比如,我们可以通过执行匿名:
var xhr = (function() {
var hr; // 定义局部 xhr 对象, 这里命名 hr
if (window.XMLHttpRequest) {
hr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
// IE
var versions = [
"Msxml2.XMLHttp.5.0",
"Msxml2.XMLHttp.4.0",
"Msxml2.XMLHttp.3.0",
"Msxml2.XMLHttp",
"Microsoft.XMLHttp"
];
try {
for (var i = ; i < versions.length; i++) {
hr = new ActiveXObject(versions[i]);
break;
}
} catch (error) {}
}
return hr; // 返回我们最后的 xhr 对象,如果宿主环境不提供 XMLHttpRequest 及 ActiveXObject, 返回 undefined
})();
构建了 xhr 对象之后,我们可以通过的来进行请求的发送。
xhr.open('GET', 'http://www.example.com');
xhr.send();
这是最简单最典型的发送请求的做法。只需要短短 2 行,我们就可以执行请求发送动作。
实际上 XMLHttpRequest.open 这个的参数不止两个这么少,一共有 5 个参数:
xhrReq.open(method, url, async, user, password);
这些参数分别代表着:
其中,user 和 password 都是用于认证用途。而前 3 个参数是我们经常都会使用到的。这里着重说的是参数 async。认情况下,async 为 true,代表着请求将是异步的。当然我们也可以设置为 false,这样我们就可以同步请求了。然而,事实上我们应该尽量不这么做,因为同步的请求会阻塞我们的UI和一切活动,造成的体验非常不好。
到目前为止,如果你也跟着做的话应该能看到已经可以发送 Ajax 请求了,虽然它是失败的,因为你并没有正确的服务能够处理这个请求。如果你在浏览器上运行,打开控制台,你应该会得到这样的:
在数据交互中,我们经常会使用 GET 请求来数据,现在假设我们有简单的GET请求,接口 http://localhost:8080/simple/get
,附带 query参数 为 mk=网
,那么我们可以构建块:
xhr.open("GET", "http://localhost:8080/simple/get?mk=网");
xhr.send();
查看图:
从上图可以看到,浏览器控制台面板上,我们进行 GET 发送请求的过程中,在 Headers 上,可以看到 Query String Parameters 附带的信息完全正确,我们的 GET 请求构造成功。
事实上我们除了要数据,提交数据也是非常重要。在 Ajax 中,我们通常使用 POST 来进行数据创建工作。
话不多说,上:
xhr.open("POST", "http://localhost:8080/simple/post");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("mk=网&class=ajax");
查看图:
基本和上面 GET 请求类似,这里我们构造了 POST 请求,请求的 url 为 http://localhost:8080/simple/post
,发送请求的参数有两个,分别为 mk=网
和 class=ajax
。从浏览器的控制台面板上可以看到,在 Headers 上,Form Data 部分正是我们要发送的数据,数据发送正常。这里两个地方需要注意:
XMLHttpRequest.setRequestHeader()
是请求HTTP 请求头部的,因此设置 Content-type 自然也是通过这个来实现。该需要在 和
send()
之间使用。
这一小节也可以当做附录来看,主要罗列一些常见的 Content-type 类型,给出参照,我们在了解之余,在实际使用 Ajax 的过程中,也可以随时回来翻看: