有时候我们在做一个动态/静态网页,网页中的某部分需要从服务器获取值但是不能把整个页面都提交到服务器,也就是要对页面做局部刷新,也就是对整个网页无刷新更新值。在这种情况下就需要用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页面的局部刷新的更多相关文章

  1. ajax跳转到新的jsp页面(局部刷新)

    ajax可以实现局部刷新页面,即在不刷新整个页面的情况下更新页面的局部信息. 项目中遇到一个问题:在用户列表也,当点击某个按钮时需要去查询用户的信息,查询成功跳转到用户详情界面:查询失败,则在原页面弹 ...

  2. 如何用php+ajax实现页面的局部刷新?(转)

    client.html XML/HTML code   ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!DOCTYPE ...

  3. 使用Ajax在HTML页面中局部刷新页面(左边菜单右边页面)

    转载自:https://blog.csdn.net/Cenmen_17714/article/details/80969008 index.html <a href="javascri ...

  4. 使用$.post方式来实现页面的局部刷新功能

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. 通过page页面与portlet的结合实现报表的局部刷新

    场景:系统已经存在两个报表,报表A与B,A与B之间可以通过省份进行追溯. 如下图:点击 报表[销售数据按区域]中的北京市 追溯到报表[销售数据按省份] 需求:让上面的操作在一个page里面刷新,实现页 ...

  6. ASP.Net 在Update Panel局部刷新后 重新绑定JS方法

    我们知道Asp.Net中的Update Panel可以完成页面的局部刷新(实质上是Ajax),但是局部刷新完后,此区域的控件上所绑定的JS方法就会失效,因为我们用如下方法来重新绑定. var prm ...

  7. jquery实现页面局部刷新

    后台管理中总是使用frameset进行分成部分进行管理,但是感觉很不好用,尤其是页面间调转还要判断window.parent,太令我费神了,于是学习使用XMLHttpRequest进行页面局部刷新.代 ...

  8. Webform——页面局部刷新

    有一些数据控件,每次更改它的值后,都会重新查询数据库,然后再重新显示出来. 这样每次都会刷新全部页面,如果是一些信息量很庞大的页面,就会出现卡顿的现象,为了避免这种情况,就用到了局部刷新. 所用到的控 ...

  9. ASP.Net用jQuery ajax实现页面局部刷新

    刚开始的时候使用asp的updatepanel控件实现局部刷新,而且在本地运行正确,但是部署到服务器上就变成整个页面全部刷新了.服务器用的是Windows server2000,本地机子上用的是win ...

随机推荐

  1. ZenCoding[Emmet]語法簡介【轉】

    快速指南 下面是一些常用的Zen Coding功能,目前VS2013的Web Essentials插件已经支持. '#' 创建一个id特性 '.' 创建一个类特性 '[]' 创建一个自定义特性 '&g ...

  2. 解决Iframe session过期,登录界面无法全页刷新

    在登录界面增加如下js代码: <script language=”JavaScript”> if (window != top) top.location.href = location. ...

  3. java的内存管理 对象的分配与释放

    分配 程序员通过new为每个对象申请内存空间(基本类型除外),所有对象都在堆中分配空间:释放:对象的释放是由垃圾回收机制决定和执行的. Java内存分为两种:栈内存和堆内存 (1)在函数中定义的基本类 ...

  4. 当 PHP 遇上 MongoDB

    FROM:http://www.cstor.cn/textdetail_7995.html 之前笔者出了一篇文章是教大家在 Linux 下安装 MongoDB,并且透过 Mongo Client 操作 ...

  5. JAX-RS之queryparam、PathParam、DefaultValue、FormParam、Context、RestController等

    这几天做东西接触了JAX-RS的东西,没有系统的从开始就学,只是单纯去复制粘贴的用,主要用到了几个Annotations变量,具体如下: queryparam.PathParam.FormParam. ...

  6. Java 数组的浅拷贝和深拷贝

    浅拷贝: 在堆内存中不会分配新的空间,而是增加一个引用变量和之前的引用指向相同的堆空间. int[] a = {1,2,3,4,5}; int[]b = a; public class Test { ...

  7. rmmod: can't change directory to '/lib/modules': No such file or directory

    [root@iTOP-4412]# mount /dev/sda1 /mnt/udisk/ [root@iTOP-4412]# insmod /mnt/udisk/linux/hello.ko  [ ...

  8. ubuntu14.04安装python3.7.1

    https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tgz python3.7.1 提示 ModuleNotFoundError: No modu ...

  9. Spring BeanPostProcessor与动态加载数据源配置

    前言: 本文旨在介绍Spring动态配置数据源的方式,即对一个DataSource的配置诸如jdbcUrl,user,password,driverClass都通过运行时指定,而非由xml静态配置定死 ...

  10. Eclipse 模拟http 请求插件Rest Client

    eclipse update 网址  http://nextinterfaces.com/http4e/install/ 参考 http://www.nextinterfaces.com/eclips ...