html页面的局部刷新

      有时候我们在做一个动态/静态网页,网页中的某部分需要从服务器获取值但是不能把整个页面都提交到服务器,也就是要对页面做局部刷新,也就是对整个网页无刷新更新值。在这种情况下就需要用JS和XMLHttpRequest对象的配合实现,本片文章记录怎样才能做到整张网页的局部刷新以备日后回顾。

文章分为两部分:XMLHTTPRequest介绍;用XMLHTTPRequest和JavaScript实现局部刷新。

第一部分

我们了解一下XMLHTTPRequest。

XMLHTTPRequest对象可以在不向服务器提交整个页面的情况下,实现局部更新网页。当页面全部加载完毕后,客户端通过该对象向服务器请求数据,服务器端接受数据并处理后,向客户端反馈数据。 XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。XMLHttpRequest 可以同步或异步返回 Web 服务器的响应,并且能以文本或者一个 DOM 文档形式返回内容。

使用XMLHTTPRequest的时候我们不用太关心浏览器支持的问题。实际上,XMLHTTPRequest得到了所有现代浏览器较好的支持。唯一的浏览器依赖性涉及XMLHTTPRequest对象的创建。在IE5和IE6中,必须试用IE特定的ActiveXObject() 构造函数才能创建,但是现在还有多少人在用IE5和IE6呢?。。。

简单了解什么是XMLHTTPRequest之后,我们看一下怎么创建XMLHTTPRequest对象。

不同的浏览器要使用不同的方法创建XMLHTTPRequest对象:IE用ActiveObject创建,其它的浏览器用名为XMLHttpRequest的JavaScript内建对象。貌似看起来创建一个所有浏览器都支持的XMLHTTPRequest有点复杂,不过我们可以用以下简单的代码创建:

var XMLHttp=null;//创建变量XMLHttp,作为XMLHTTPRequest对象

if (window.XMLHttpRequest)//针对除IE之外的浏览器做判断,看是否能创建XMLHTTPRequest

{

XMLHttp=new XMLHttpRequest()//能的话就直接创建

}else if (window.ActiveXObject)

{

XMLHttp=new ActiveXObject("Microsoft.XMLHTTP")//如果不能,就是IE了,用ActiveXObject创建

}

以上代码中,在判断IE处使用了传入Microsoft.XMLHTTP这个参数创建XMLHTTPRequest对象,这个方法适用于IE5.5及更高版本,但是不是创建XMLHTTPRequest对象最快的方法,我们看改进后的:

 

function GetXmlHttpObject()

{

var xmlHttp=null;

try {

// 针对Firefox, Opera 8.0+, Safari浏览器创建

xmlHttp=new XMLHttpRequest();

}

catch (e)

{

// 不行的话就是IE了

try {

xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");//这个是最快的

}

catch (e) {

xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");//为了以防万一,如果错误后我们再用慢的方式

}

}

return xmlHttp;

}

上面这段代码,在对IE的判断上我们用XMLHttp=new ActiveXObject("Msxml2.XMLHTTP")创建,这在IE6+版本可用,如果错误,则用适合IE5.5的老方法创建。

知道了怎样创建后,我们看一下XMLHTTPRequest的属性。

XMLHTTPRequest有5个属性:readyState、responseText、responseXML、status、statusText。

readyState

这是HTTP请求的状态,值有5个,初次创建XMLHTTPRequest时是0,直到HTTP响应结束,这个值一直增加到4。这5个状态的名称和含义如下表:

 

 

状态

名称

描述

0

Uninitialized

初始化状态。XMLHttpRequest 对象已创建或已被 abort() 方法重置。

1

Open

open() 方法已调用,但是 send() 方法未调用。请求还没有被发送。

2

Send

Send() 方法已调用,HTTP 请求已发送到 Web 服务器。未接收到响应。

3

Receiving

所有响应头部都已经接收到。响应体开始接收但未完成。

4

Loaded

HTTP 响应已经完全接收。

 

这里要说明一下,readyState的值不会递减,除非在请求的过程中调用了abort() 或 open() 方法。每次值增加的时候都会触发onreadystatechange事件。

responseText

到目前为止从服务器接收到的响应体(不包括头部)。如果还没有接收到数据的话,就是空字符串。

根据上一个属性,我们可以知道,当readyState值为3之前,responseText的值都为空,直到为4的时候,才是这个属性保存了完整的HTTP响应体。

responseXML

对请求的响应,解析为 XML 并作为 Document 对象返回。如果响应体不是“text/xml”返回null。

Status

由服务器返回的 HTTP 状态代码,如 200 表示成功,而 404 表示 "Not Found" 错误。当 readyState 小于 3 的时候读取这一属性会导致一个异常。

statusText

这个属性用名称而不是数字指定了请求的 HTTP 的状态代码。也就是说,当状态为 200 的时候它是 "OK",当状态为 404 的时候它是 "Not Found"。和 status 属性一样,当 readyState 小于 3 的时候读取这一属性会导致一个异常。

以上是XMLHTTPRequest的属性,接下来,我们看一下它的方法。

XMLHTTPRequest对象的方法有6个:abort()、getAllResponseHeaders()、getResponseHeader()、open()、send()、setRequestHeader()

abort()

这个方法是取消当前响应,关闭与服务器的连接并结束任何发生或没有发生的网络活动。

一旦调用了这个方法,XMLHttpRequest对象会重置readState为0,一般会用在请求时间过长,响应不再必要的时候。

 

getAllResponseHeaders()

把 HTTP 响应头部作为未解析的字符串返回。

如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 "" 隔开。

getResponseHeader()

返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。

该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值。

open()

此方法是初始化HTTP请求参数,比如URL和HTTP的请求方法(get,post等)。

send()

试用传递给open()方法的参数发送HTTP请求。

setRequestHeader()

向一个打开但未发送的请求设置或添加一个 HTTP 请求。

以上便是XMLHTTPRequest的所有方法,如果看到这里不太累的话,下面我们了解一下open()和send()方法怎么用。

XMLHttpRequest.open()

初始化 HTTP 请求参数

语法

open(method, url, async, username, password)method 参数是用于请求的 HTTP 方法。值包括 GET、POST 和 HEAD。

url 参数是请求的主体。大多数浏览器实施了一个同源安全策略,并且要求这个 URL 与包含脚本的文本具有相同的主机名和端口。

async 参数指示请求使用应该异步地执行,值为true和false。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。

username 和 password 参数是可选的,为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。

说明

这个方法初始化请求参数以供 send() 方法稍后使用。它把 readyState 设置为 1,删除之前指定的所有请求头部,以及之前接收的所有响应头部,并且把 responseText、responseXML、status 以及 statusText 参数设置为它们的默认值。当 readyState 为 0 的时候(当 XMLHttpRequest 对象刚创建或者 abort() 方法调用后)以及当 readyState 为 4 时(已经接收响应时),调用这个方法是安全的。当针对任何其他状态调用的时候,open() 方法的行为是为指定的。

除了保存供 send() 方法使用的请求参数,以及重置 XMLHttpRequest 对象以便复用,open() 方法没有其他的行为。要特别注意,当这个方法调用的时候,实现通常不会打开一个到 Web 服务器的网络连接。

XMLHttpRequest.send()

发送一个 HTTP 请求

语法

send(body)如果通过调用 open() 指定的 HTTP 方法是 POST 或 GET,body 参数指定了请求体,作为一个字符串或者 Document 对象。如果请求体不是必须的话,这个参数就为 null。对于任何其他方法,这个参数是不可用的,应该为 null(有些实现不允许省略该参数)。

说明

这个方法导致一个 HTTP 请求发送。如果之前没有调用 open(),或者更具体地说,如果 readyState 不是 1,send() 抛出一个异常。否则,它发送一个 HTTP 请求,该请求由以下几部分组成:

之前调用 open() 时指定的 HTTP 方法、URL 以及认证资格(如果有的话)。 之前调用 setRequestHeader() 时指定的请求头部(如果有的话)。 传递给这个方法的 body 参数。 一旦请求发布了,先触发 onreadystatechange 事件句柄,随后send() 把 readyState 设置为 2,并触发 onreadystatechange 事件句柄。

如果之前调用的 open() 参数 async 为 false,这个方法会阻塞并不会返回,直到 readyState 为 4 并且服务器的响应被完全接收。否则,如果 async 参数为 true,或者这个参数省略了,send() 立即返回,并且正如后面所介绍的,服务器响应将在一个后台线程中处理。

如果服务器响应带有一个 HTTP 重定向,send() 方法或后台线程自动遵从重定向。当所有的 HTTP 响应头部已经接收,send() 或后台线程把 readyState 设置为 3 并触发 onreadystatechange 事件句柄。如果响应较长,send() 或后台线程可能在状态 3 中触发 onreadystatechange 事件句柄:这可以作为一个下载进度指示器。最后,当响应完成,send() 或后台线程把 readyState 设置为 4,并最后一次触发事件句柄。

第二部分

用XMLHttpRequest对象和JavaScript做网页局部刷新

我们以无动态刷新省市级联为例来做页面的局部刷新。假定,在某一个活动报名的页面(默认.net平台)上需要录入用户的信息,比如省市、姓名、性别、电话号码、邮箱等信息。在这个报名表单中,我们把选择省市处做成下拉菜单。如果这个页面用自动回发,用户在每选择一次省份的时候页面就会刷新一次,肯定会降低用户体验,我们把它做成无刷新的方式,XMLHTTPRequest对象会默默无闻的向服务器请求数据,不打扰用户,用户在页面停留的平均时间也会延长,体验会更好。

下面我们就用第一部分介绍的XMLHTTPRequest对象实现局部刷新。

首先,我们实例化一个XMLHTTPRequest对象:

// JavaScript Document

function GetXMLHttpRequest()

        {

            var xmlhttp=null;

            try

            {

                xmlhttp =new ActiveXObject("Msxml2.XMLHTTP");

            }

            catch(e)

            {

                try

                {

                    xmlhttp =new ActiveXObject("Microsoft.XMLHTTP");

                }

                catch(oc)

                {

                    xmlhttp =null;

                }

            }

            if(!xmlhttp && typeof XMLHttpRequest != "undefined")

            {

                xmlhttp =new XMLHttpRequest();

            }

            return xmlhttp;

        }

然后,封装一个获取服务器数据的JS函数:

function GetServerData(obj) {

            var FValue = obj.value;//传过来的值,可以作为一个参数传入数据接口。

            var weburl = "http://www.example.com/index.ashx?provinceid=" + FValue;//请求的url地址,这个地址仅为示例,实际不存在

            var xmlhttp = GetXMLHttpRequest();//实例化XMLHTTPRequest            xmlhttp.open("get",weburl,true);//调用open()方法      xmlhttp.onreadystatechange=function()//readyState 属性改变的时候调用的事件句柄函数

            {

                if(xmlhttp.readyState==4)//服务器已经成功返回数据

                {

var result=xmlhttp.responseText; //得到服务器返回的数据,然后怎么处理这些数据,看你的了

                }

            }

            xmlhttp.send(null);

        }

到这里,网页的局部刷新的最关键的部分就完成了,剩下的就是根据具体的需要操作服务器返回的数据了。

如果看到这里还是有点不懂,看一下下面的这个小例子,以下是源码

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NoRefresh.aspx.cs" Inherits="WebApplication1.NoRefresh" %>

 

<!DOCTYPE html>

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <title>页面局部刷新</title>

    <script type="text/javascript">

        function GetXMLHttpRequest() {

            var xmlhttp = null;

            try {

                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");

            }

            catch (e) {

                try {

                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

                }

                catch (oc) {

                    xmlhttp = null;

                }

            }

            if (!xmlhttp && typeof XMLHttpRequest != "undefined") {

                xmlhttp = new XMLHttpRequest();

            }

            return xmlhttp;

        }

        function GetServerData(obj) {

            var FValue = obj.value;

            var weburl =  "http://www.example.com/index.ashx?provinceid=" + FValue; //请求的url地址,这个地址仅为示例,实际不存在

            var xmlhttp = GetXMLHttpRequest();

            xmlhttp.open("get", weburl, true);

            xmlhttp.onreadystatechange = function () {

                if (xmlhttp.readyState == 4) {

                    //得到服务器返回的数据

                    var result = xmlhttp.responseText;

                    document.getElementById("<%=ddl_city.ClientID %>").length = 0;

                    document.getElementById("<%=ddl_city.ClientID %>").options.add(new Option("请选择城市", "0"));

                    if (result != "") {

                        var cityArry = eval("(" + result + ")");//string --> object这里我们模拟获取的数据是JSON数组。切记,从服务器上获取的JSON数组一定要转换为object数据类型,否则无法获取值。

                        for (var i = 0; i < cityArry.City.length; i++) {

                            var cityid = cityArry.City[i].CityID;

                            var cityname = cityArry.City[i].CityName;                            document.getElementById("<%=this.ddl_city.ClientID %>").options.add(new Option(cityname, cityid));

                        }

                    }

                }

            }

            xmlhttp.send(null);

        }

    </script>

</head>

<body style="background:url(‘images/bodybg.png‘) repeat top;">

    <form id="form1" runat="server">

    <div style="width:200px; height:100px; margin-top:50px; margin-left:100px;">

        省份:<asp:DropDownList ID="ddl_province" runat="server" onchange="GetServerData(this)">

            <asp:ListItem Value="0">请选择省份</asp:ListItem>

            <asp:ListItem Value="1">北京</asp:ListItem>

            <asp:ListItem Value="16">河南</asp:ListItem>

           </asp:DropDownList><br />

        城市:<asp:DropDownList ID="ddl_city" runat="server">

            <asp:ListItem Value="0">请选择市区</asp:ListItem>

           </asp:DropDownList>

    </div>

    </form>

</body>

</html>

 另:页面用到的JSON数组

{"City":[{"CityID":"152","CityName":"郑州市"},{"CityID":"153","CityName":"开封市"},{"CityID":"154","CityName":"洛阳市"},{"CityID":"155","CityName":"平顶山市"},{"CityID":"156","CityName":"安阳市"},{"CityID":"157","CityName":"鹤壁市"},{"CityID":"158","CityName":"新乡市"},{"CityID":"159","CityName":"焦作市"},{"CityID":"160","CityName":"濮阳市"},{"CityID":"161","CityName":"许昌市"},{"CityID":"162","CityName":"漯河市"},{"CityID":"163","CityName":"三门峡市"},{"CityID":"164","CityName":"南阳市"},{"CityID":"165","CityName":"商丘市"},{"CityID":"166","CityName":"信阳市"},{"CityID":"167","CityName":"周口市"},{"CityID":"168","CityName":"驻马店市"}]}

html页面的局部刷新,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。