首先,我们定义方法createXHR()用来创建XMLHttpRequest对象,前面我们提到IE6或者更老的版本不支持XMLHttpRequest()方法来创建XMLHttpRequest对象,所以我们要在createXHR()方法中,增加判断当前浏览器是否IE6或更老的版本,如果是,就要通过MSXML库的一个ActiveX对象实现。因此,在IE中可能遇到三种不同版本的XHR对象(MSXML2.XMLHttp6.0,MSXML2.XMLHttp3.0和MSXML2.XMLHttp)。
// Creates a XMLHttpRequest object bases on web broswer. function createXHR() { // Checks whether support XMLHttpRequest or not. if (typeof XMLHttpRequest != "undefined") { return new XMLHttpRequest(); } // IE6 and elder version. else if (typeof ActiveXObject != "undefined") { if (typeof arguments.callee.activeXString != "string") { var versions = [ "MSXML2.XMLHttp6.0", "MSXML2.XMLHttp3.0", "MSXML2.XMLHttp"]; for (var i = 0; i < versions.length; i++) { try { var xhr = new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; return xhr; } catch (ex) { throw new Error(ex.toString()); } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No XHR object available"); } } return null; } $(document).ready(function() { GetDataFromServer(); });前面我们定义了一个比较通用的方法用来创建XMLHttpRequest对象,并且它支持IE6或更老版本创建XMLHttpRequest对象,接下来我们将通过Ajax方法请求数据。
function GetDataFromServer() { // Creates a XMLHttpRequest object. var req = new createXHR(); if (req != null) { req.onreadystatechange = function() { if (req.readyState == 4) { if ((req.status >= 200 && req.status < 300) || req.status == 304) { ////alert(req.responseText); var jsonTextDiv = document.getElementById("jsonText"); // Deserializes JavaScript Object Notation (JSON) text to produce a JavaScript value. var data = JSON.parse(req.responseText); for (var i = 0; i < data.length; i++) { var item = data[i]; var div = document.createElement("div"); div.setAttribute("class", "dataItem"); // Inserts data into the html. div.innerHTML = item.Name + " sold " + item.Qty + "; Product number: " + item.SerialNumber; jsonTextDiv.appendChild(div); } } else { alert("Request was unsuccessful: " + req.status); } } }; // Sends a asyn request. req.open("GET", "ProductInfo.ashx", true); req.send(null); } }由于前面我们介绍过Ajax发生请求的方法,所以不再重复介绍了,但我们注意到GetDataFromServer()方法中,获取responseText数据(JSON格式),然后通过parse()方法把JSON格式数据转换为Javascript对象,最后把数据插入到div中,页面呈现效果如下:
图3 Ajax请求结果
现在,我们成功地把数据输出到页面当中,也许用户还会觉得用户体验不好,那么我们给就该页面增加CSS样式。
由于时间的关系,我们已经把CSS样式定义好了,具体如下:
#header { width: 100%; margin-left: 10px; margin-right: 10px; background-color:#480082; color: #FFFFFF; } body { margin-left: 40px; margin-right: 40px; } div#jsonText { background-color: #d9d9d9; -webkit-border-radius: 6px; border-radius: 6px; margin: 10px 0px 0px 0px; padding: 0px; border: 1px solid #d9d9d9; } div.dataItem { font-family: Verdana, Helvetica, sans-serif; color: #434343; padding: 10px; } div.dataItem:nth-child(2n) { background-color: #fafafa; } div.dataItem:first-child { -webkit-border-top-left-radius: 6px; -webkit-border-top-right-radius: 6px; border-top-left-radius: 6px; border-top-right-radius: 6px; } div.dataItem:last-child { -webkit-border-bottom-left-radius: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; }我们刷新一下页面,OK现在页面效果好多了。
图4 Ajax请求结果
同源策略与跨源策略上面我们获取页面和数据都是在同源请求情况下,也就是说,客户端浏览器请求的页面和数据都是属于同一域名、同一端口和同协议。
同源策略:阻止从一个域上加载的脚本获取或操作另一个域上的文档属性。也就是说,受到请求的URL的域必须与当前Web页面的域相同、相同端口。这意味着浏览器隔离来自不同源的内容,以防止它们之间的操作。
图5同源请求过程
在一些情况下,我们不可以避免地要地需要从其他域名或服务器中跨域请求数据,但前面提到Ajax只能向同一个域中使用相同端口和协议的URL中发送请求;如果URL与启动请求的页面有任何差别,都会引发安全错误。
跨源策略(CORS):是一个Web浏览器技术规范,它定义了一个方法让Web服务器允许其他域名页面访问它的资源。跨源策略定义了一个方法让浏览器和服务器可以交互决定是否允许跨源请求。
图6跨源请求过程
大家注意到同源请求中我们使用的是JSON格式,但在跨源请求中却是使用JSONP,这时大家可能有点困惑,坦然我刚开始学习的时候也是这样的。