用AJAX实现联动下拉菜单(Cascading DropDownList Using AJAX)

原来一直以为只有.NET Framework 2.0才可以使用AJAX,但是同时也听说其实AJAX技术说到底并不是一个全新的技术而是对一些现有技术的新应用。以下这篇文章很好的解释了这个问题。(此文章英语原文可以见另外一篇文章--DropDown Box Using AJAX 或者你可以直接到这里查看原文)

什么是AJAX?

AJAXAsynchronous JavaScript and XML(异步的JavaScript和XML)的字母缩写,是一种创建交互式网络应用的开发技术。AJAX存在的主要目的是为了增加用户使用网络应用的体验。AJAX技术通过少量的数据回传和页面的局部更新防止传统网络应用在用户发出请求后需要重新载入整个页面的问题,使页面具有更友好的交互性、更快的响应速度和更好的可用性。

使用XmlHttp对象

什么是XmlHttp对象?(以下解释信息来源: http://www.jsfan.org/reference/xmlhttp/2007020744.htm)

最通用的定义为:XmlHttp是一套可以在Javascript、VbScript、Jscript等脚本语言中通过http协议传送或从接收XML及其他数据的一套API。XmlHttp最大的用处是可以更新网页的部分内容而不需要刷新整个页面。

来自MSDN的解释:XmlHttp提供客户端同http服务器通讯的协议。客户端可以通过XmlHttp对象(MSXML2.XMLHTTP.3.0) 向http服务器发送请求并使用微软XML文档对象模型Microsoft® XML Document Object Model (DOM)处理回应。

来自维基百科的解释:XMLHTTP is a set of APIs that can be used by JavaScript, JScript, VBScript and other web browser scripting languages to transfer XML or other data to and from a web server using HTTP. The biggest advantage of XMLHTTP is the ability to dynamically update a webpage without reloading the entire webpage or using software plugins. It is used by many websites to implement responsive and dynamic web applications. ...(这个翻译过来基本就是“最通用的定义”)

现在的绝对多数浏览器都增加了对XmlHttp的支持,IE中使用ActiveXObject方式创建XmlHttp对象,其他浏览器如:Firefox、Opera等通过window.XMLHttpRequest来创建xmlhttp对象。

一个XmlHttp对象可以通过如下方式来进行创建:

< script language = " javascript " >
  
// Global XMLHTTP Request object
var  XmlHttp;

// Creating and setting the instance of appropriate XMLHTTP Request object to 
//
a "XmlHttp" variable  
function  CreateXmlHttp()
{
 
//Creating object of XMLHTTP in IE
 try
 
{
  XmlHttp 
= new ActiveXObject("Msxml2.XMLHTTP");
 }

 
catch(e)
 
{
  
try
  
{
   XmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP");
  }
 
  
catch(oc)
  
{
   XmlHttp 
= null;
  }

 }

 
//Creating object of XMLHTTP in Mozilla and Safari 
 if(!XmlHttp && typeof XMLHttpRequest != "undefined"
 
{
  XmlHttp 
= new XMLHttpRequest();
 }

}

</ script >

 

向服务器端发送请求

我们可以通过XmlHttp对象从服务器端获得需要的数据。

   
   
var  requestUrl  =   " WebForm2.aspx "   +   " ?SelectedCountry= "   +  (selectedCountry);
 CreateXmlHttp();
 
 
//  If browser supports XMLHTTPRequest object
  if (XmlHttp)
 
{
  
//Setting the event handler for the response
  XmlHttp.onreadystatechange = HandleResponse;
  
  
//Initializes the request object with GET (METHOD of posting), 
  //Request URL and sets the request as asynchronous.
  XmlHttp.open("GET", requestUrl,  true);
  
  
//Sends the request to server
  XmlHttp.send(null);  
 }

其中:

1、XmlHttp.onreadystatechange 是一个事件,如同button的onclick事件一样。HandleResponse是在时间触发后需要调用的处理函数。这里可以对照onclick事件进行理解,比如我们需要实现在点击某个按钮后弹出一个带有hello world内容的信息提示框,那么我们可以有如下代码:

 

function  showMessageBox()
{
      alert(
'hello world!');
}


< input type = " button "  value = " click me "  onclick = " showMessageBox(); "   />

2、XmlHttp.open()方法用于创建一个新的http请求,并指定此请求的方法、URL以及验证信息。具体语法为:

 

 

XMLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);

 

bstrMethod
http方法,例如:POST、GET、PUT及PROPFIND。大小写不敏感。

bstrUrl
请求的URL地址,可以为绝对地址也可以为相对地址。

varAsync[可选]
布尔型,指定此请求是否为异步方式,默认为true。如果为真,当状态改变时会调用onreadystatechange属性指定的回调函数。

bstrUser[可选]
如果服务器需要验证,此处指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。

bstrPassword[可选]
验证信息中的密码部分,如果用户名为空,则此值将被忽略。

3、XmlHttp.send()方法将XmlHttp对象发送到服务器端。

我们再回到本小节最上面的代码,这段代码展示了如何构造一个异步方式的xmlHttp对象,并向webpage2.aspx页面发送请求,这个请求中包含了请求查询字符串(URL 参数),在这里就是通过第一个下拉菜单选择的国家。

处理来自客户端的请求

当服务器接收到来自客户端的请求(实际从XmlHttp.open中的参数我们可以看出我们请求的实际是另外一个页面),这个页面将执行服务器端的处理代码,执行结果同样通过XmlHttp对象回传给客户端。请求页面的后台处理代码如下所示,这段代码主要完成载入包含国家和州信息的XML文件,然后根据URL参数传过来的国家名称查找其包含的州列表,然后通过短横杠("-")将各个州连接成一个字符串,并将这个字符串通过标准输出流(Response)的Write(Response.Write())方法发送给客户端。


    
    
Dim  xList  As  XmlNodeList
Dim  xNode  As  XmlNode
Dim   Str   As   String
xmlDoc.Load(Server.MapPath(
" CountriesAndStates.xml " ))

Dim  Country  As   String   =  Request.QueryString( " SelectedCountry " )
Dim  query  As   String   =  ( " /countries/country[@name=' "   &  country  &   " '] " )
xlist 
=  xmlDoc.SelectNodes(query)

Response.Clear()
 
For   Each  xNode  In  xList
     
If  xNode.HasChildNodes  =   True   Then
          
For   Each  xN  As  XmlNode  In  xNode.ChildNodes
               
Str   &=  xN.InnerText  &   " - "
          
Next
     
End   If
Next

Response.Clear()
Response.ContentType 
=   " text/xml "
Response.Write(
str )
Response.End()

从XmlHttp对象中得到来自服务器的数据

在下表中列举的是XMLHttp(IE, 在FireFox和Netscape中为XMLHttpRequest)对象所处的有效状态。

Value(值)

Description(描述)

0

Uninitialized 对象已建立,但是尚未初始化(尚未调用open方法)

1

Loading对象已建立,尚未调用send方法

2

Loaded send方法已调用,但是当前的状态及http头未知

3

Interactive已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误

4

Complete 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据

The list of status codes for the HTTP status is given below:

以下列举的是HTTP返回码所代表的意思,注意这些码都是已经通过服务器端完成处理后返回客户端的代码。

1xx Informational (正在获取信息)

已经收到了来自客户端的请求,但是还没有处理完成,需要进一步进行处理。

  • 100: Continue
  • 101: Switching Protocols
2xx Success (操作成功)

表示一个操作已经成功完成(如:请求已经被成功接收,请求已经被理解等)

  • 200: OK
  • 201: Created
  • 202: Accepted
  • 203: Non-Authoritative Information
  • 204: No Content
  • 205: Reset Content
  • 206: Partial Content
  • 207: Multi-Status
3xx Redirection (重定向)

客户端需要进行进一步操作和处理才能完成请求。

  • 300: Multiple Choices
  • 301: Moved Permanently. This and all future requests should be directed to another URI.
  • 302: Found this the most popular redirect code, but also an example of industrial practice contradicting the standard. HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect (the original describing phrase was "Moved Temporarily"), but popular browsers implemented it as a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to disambiguate between the two behaviors. However, majority of web applications and frameworks still use the 302 status code as if it were the 303.
  • 303: See Other (since HTTP/1.1). The response to the request can be found under another URI using a GET method.
  • 304: Not Modified
  • 305: Use Proxy (since HTTP/1.1). Many HTTP clients (such as Mozilla and Internet Explorer) don't correctly handle responses with this status code.
  • 306 is no longer used, but reserved. Was used for 'Switch Proxy'.
  • 307: Temporary Redirect (since HTTP/1.1). In this occasion, the request should be repeated with another URI, but future requests can still be directed to the original URI. In contrast to 303, the original POST request must be repeated with another POST request.
4xx Client Error(客户端错误)

来自客户端的请求存在错误导致服务器不能正常的处理请求的处理。如:404错误,表示无法找到请求的资源,这个是我们平时比较常见的错误。

  • 400: Bad Request
  • 401: Unauthorized. Similar to 403/Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided. See basic authentication scheme and digest access authentication.
  • 402: Payment Required. The original intention was that this code might be used as part of some form of digital cash/micropayment scheme, but that has not happened, and this code has never been used.
  • 403: Forbidden
  • 404: Not Found
  • 405: Method Not Allowed
  • 406: Not Acceptable
  • 407: Proxy Authentication Required
  • 408: Request Timeout
  • 409: Conflict
  • 410: Gone
  • 411: Length Required
  • 412: Precondition Failed
  • 413: Request Entity Too Large
  • 414: Request-URI Too Long
  • 415: Unsupported Media Type
  • 416: Requested Range Not Satisfiable
  • 417: Expectation Failed
  • 449: Retry With A Microsoft extension: The request should be retried after doing the appropriate action.
5xx Server Error(服务器端错误)

服务器在无法完成一个合法的请求时将向客户端返回服务器错误代码。我碰到的最多的是503错误,即Serivce Unavailable,即服务不可用。

  • 500: Internal Server Error
  • 501: Not Implemented
  • 502: Bad Gateway
  • 503: Service Unavailable
  • 504: Gateway Timeout
  • 505: HTTP Version Not Supported
  • 509: Bandwidth Limit Exceeded. This status code, while used by many servers, is not an official HTTP status code.
   
   
if (XmlHttp.readyState  ==   4 )
 
{
  
// To make sure valid response is received from the server, 
  // 200 means response received is OK
  if(XmlHttp.status == 200)
  
{  
   ClearAndSetStateListItems(XmlHttp.responseText);
  }

  
else
  
{
   alert(
"There was a problem retrieving data from the server." );
  }

 }

以上代码展现了如何从一个XmlHttp对象中得到来自服务器的响应数据。XmlHttp.readyState == 4 如果成立,那么表示XmlHttp已经完全的接收了来自服务器的数据,已经可以正常的时候XmlHttp的responseText和responseBody属性。这里需要注意的是XmlHttp.readyState == 4仅仅只能说明XmlHttp对象已经完全接收了来自服务器的响应数据,但是这些数据是否是有效的,或者是否是服务器成功处理了我们的请求而返回的数据,这个无法判断,所以我们还需要通过XmlHttp.status == 200来判断是否请求已经被服务器端所正常处理了,如果请求已经被正常处理了,那么我们就可以保证XmlHttp.responseText中是我们想要的数据了,然后我们调用ClearAndSetStateListItems方法来将包含选择国家包含州信息的字符串解析并绑定到下拉菜单中。

其中ClearAndSetStateListItems代码如下:

 

function  ClearAndSetStateListItems(countryNode)
{
    
var stateList = document.getElementById("stateList");
    
//Clears the state combo box contents.
    for (var count = stateList.options.length-1; count >-1; count--)
    
{
        stateList.options[count] 
= null;
    }


    
var stateNodes = countryNode.split("-");
    
//window.alert(stateNodes) 
    var textValue; 
    
var optionItem;
    
//Add new states list to the state combo box.
    for (var count = 0; count < stateNodes.length; count++)
    
{
           textValue 
= (stateNodes[count]);
        optionItem 
= new Option( textValue, textValue,  falsefalse);
        
//window.alert(textValue); 
        //stateList.appendChild(textValue); 
        stateList.options[stateList.length] = optionItem;
    }

}

 

可以通过XmlHttp的responseText、responseXML或responseBody属性来获得从服务器端返回的响应数据。

  1. ResponseText 返回数据为字符性文本数据 数据源为任何文本性数据;
  2. ResponseXML 返回数据为DOM对象,可以用JS通过DOM进行加工控制的,但源数据必须是XML
  3. Responsebody 返回的是二进制数据,可以通过Adodb.Stream进行加工控制,数据源可以为任何数据。

将返回的数据绑定到DropDownList中

如下面的代码那样,首先将包含州信息的responseText字符串通过"-"分开,成为字符串数组,然后通过便立数组将值分别绑定到下拉菜单中。

   
   
var  stateList  =  document.getElementById( " stateList " );
 
// Clears the state combo box contents.
  for  ( var  count  =  stateList.options.length - 1 ; count  >- 1 ; count -- )
 
{
  stateList.options[count] 
= null;
 }


 
var  stateNodes  =  countryNode.split( " - " );
 
// window.alert(stateNodes) 
  var  textValue; 
 
var  optionItem;
 
// Add new states list to the state combo box.
  for  ( var  count  =   0 ; count  <  stateNodes.length; count ++ )
 
{
     textValue 
= (stateNodes[count]);
  optionItem 
= new Option( textValue, textValue,  falsefalse);
  
//window.alert(textValue); 
  //stateList.appendChild(textValue); 
  stateList.options[stateList.length] = optionItem;
 }

This is my first article in The Code Project.

<script src="http://www.codeproject.com/script/togglePre.js" type="text/javascript"></script>

About sathesh_pandian (本文作者:))


working as a developer

Click here to view sathesh_pandian's online profile.

  
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值