上次是最简单的原生JS实现AJAX效果。不过,那简单的步骤不能适应各种不同的浏览器,尤其是万恶的IE,尤其是低版本的IE浏览器。本期就来搞定各个浏览器,以及其他各项参数的设置。
一、服务端代码
服务端代码仍然使用.NET一般处理程序,这次的逻辑略有改动,通过QueryString获取一个key为type的参数,旨在接下来演示AJAX通过GET方式传参。此type属性预设值为“DATE“/”TIME“,如果是”DATE”,服务端就返回当前日期(年月日),否则返回当前时间(时分秒)。
public class TimeHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string type = context.Request.QueryString["type"].ToUpper();
if(type == "DATE")
{
context.Response.Write(DateTime.Now.ToLongDateString());
}
else
{
context.Response.Write(DateTime.Now.ToLongTimeString());
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
二、客户端JS代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script>
window.onload = function () {
var btn = document.getElementById("btnTime");
btn.onclick = function () {
////1.声明异步对象
var xhr = false;
//2.根据浏览器类型,创建异步对象
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
//3.从下拉选项框中获取用户选中的选项
var type = document.getElementById("dType").value;
//4.拼写url,把get请求传递的参数拼接到url后边
var url = "timehandler.ashx" + "?type=" + type;
//5.打开异步对象,并设置参数
xhr.open("get", url, true);
//6.设置setRequestHeader,不使用缓存数据
xhr.setRequestHeader("If-Modified-Since", "0");
//7.设置回调函数
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var h2 = document.getElementById("time");
h2.innerHTML = xhr.responseText;
}
}
//4.发送异步请求
xhr.send(null);
}
}
</script>
</head>
<body>
<select id="dType">
<option value="DATE">年月日</option>
<option value="TIME">时分秒</option>
</select>
<h2 id="time"></h2>
<button id="btnTime">点击</button>
</body>
</html>
在客户端,用户通过选择select下拉框中的选项,然后点击btnTime按钮,获取服务器日期或时间。
与最简化的版本相比,变化点有以下几个
1.异步对象的创建。
不同的浏览器对于XMLHttpRequest对象的支持不同,这里主要指的是IE,尤其是老版本的IE,它们不支持该对象。IE老版本的浏览器支持的是MS自家的对象ActiveXObject,所以在创建的时候要先做下判断,以兼容老版本IE浏览器。
其中new ActiveXObject("Microsoft.XMLHTTP")时,传递的参数表示微软的xml语言解析器,用来解释xml语言的。就好像html文本下载到本地,浏览器会检查html的语法,解释html文本然后显示出来一样,不过不仅仅微软有。该也是有变化的,原因是微软在不同版本的浏览器中,对于该参数的解析也不同,所以也有人这么来创建异步对象
var xhr = false;
var msXmlVers = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", "Microsoft.XMLHttp"];
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
for (var i = 0; i < msXmlVers.length; i++) {
xhr = new ActiveXObject(msXmlVers[i]);
if (xhr) {
break;
}
}
}
其中msXmlVers是个数组,该数组的各个项是不同的msxml解析版本。不过这么写的人貌似不多。
话又说回来了,现在谁还写原生的Javascript代码来做AJAX?所以这里我们了解就OK了,不求甚解了。
2.GET请求传参
AJAX对于Get请求和Post请求的传参方式是不同的。
Get请求仍然通过url传参,参数仍然以键值对的形式传递。语法:url?key1=val1&key2=val2&key3=val3..... ,与普通的get请求传出别无二致。
3.禁用客户端缓存
setRequestHeader是异步对象提供的一个重要的API,它是用来设置请求报文头的。
这里:xhr.setRequestHeader("If-Modified-Since", "0");是通过设置请求报文头的"If-Modified-Since",来达到禁用客户端缓存数据的目的。
至于为什么要禁用客户端缓存数据?
在http中Last-Modified 与If-Modified-Since 都是用于记录页面最后修改时间的 HTTP 头信息,注意,在这 Last-Modified 是由服务器往客户端发送的 HTTP 头,另一个 If-Modified-Since是由客户端往服务器发送的头,可以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。而且在一些ajax应用中,要求获取的数据永远是最新的,而不是读取位于缓存中的数据,做这样的设置是非常有必要的。
那么除了这种方法禁用缓存数据以外,还有一个种方法,就是在请求的url上做手脚。比如:var url = "timehandler.ashx" + "?timestamp=" + new Date().getTime();