Dec
25
XMLHttpRequest对象是当今所有AJAX和Web 2.0应用程序的技术基础。尽管软件经销商和开源社团现在都在提供各种AJAX框架以进一步简化XMLHttpRequest对象的使用;但是,我们仍然很有必要理解这个对象的详细工作机制。
一、 引言
异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程。这一技术的优点在于,它向开发者提供了一种从Web服务器检索数据而不必把用户当前正在观察的页面回馈给服务器。与现代浏览器的通过存取浏览器DOM结构的编程代码(JavaScript)动态地改变被显示内容的支持相配合,AJAX让开发者在浏览器端更新被显示的HTML内容而不必刷新页面。换句话说,AJAX可以使基于浏览器的应用程序更具交互性而且更类似传统型桌面应用程序。
Google的Gmail和Outlook Express就是两个使用AJAX技术的我们所熟悉的例子。而且,AJAX可以用于任何客户端脚本语言中,这包括JavaScript,Jscript和VBScript。
AJAX利用一个构建到所有现代浏览器内部的对象-XMLHttpRequest-来实现发送和接收HTTP请求与响应信息。一个经由XMLHttpRequest对象发送的HTTP请求并不要求页面中拥有或回寄一个<form>元素。AJAX中的"A"代表了"异步",这意味着XMLHttpRequest对象的send()方法可以立即返回,从而让Web页面上的其它HTML/JavaScript继续其浏览器端处理而由服务器处理HTTP请求并发送响应。尽管缺省情况下请求是异步进行的,但是,你可以选择发送同步请求,这将会暂停其它Web页面的处理,直到该页面接收到服务器的响应为止。
微软在其Internet Explorer(IE) 5中作为一个ActiveX对象形式引入了XMLHttpRequest对象。其他的认识到这一对象重要性的浏览器制造商也都纷纷在他们的浏览器内实现了XMLHttpRequest对象,但是作为一个本地JavaScript对象而不是作为一个ActiveX对象实现。而如今,在认识到实现这一类型的价值及安全性特征之后,微软已经在其IE 7中把XMLHttpRequest实现为一个窗口对象属性。幸运的是,尽管其实现(因而也影响到调用方式)细节不同,但是,所有的浏览器实现都具有类似的功能,并且实质上是相同方法。目前,W3C组织正在努力进行XMLHttpRequest对象的标准化,并且已经发行了有关该W3C规范的一个草案。
本文将对XMLHttpRequest对象API进行详细讨论,并将解释其所有的属性和方法。
二、 XMLHttpRequest对象的属性和事件
XMLHttpRequest对象暴露各种属性、方法和事件以便于脚本处理和控制HTTP请求与响应。下面,我们将对此展开详细的讨论。
readyState属性
当XMLHttpRequest对象把一个HTTP请求发送到服务器时将经历若干种状态:一直等待直到请求被处理;然后,它才接收一个响应。这样以来,脚本才正确响应各种状态-XMLHttpRequest对象暴露一个描述对象的当前状态的readyState属性,如表格1所示。
表格1.XMLHttpRequest对象的ReadyState属性值列表。
ReadyState取值 描述
0 描述一种"未初始化"状态;此时,已经创建一个XMLHttpRequest对象,但是还没有初始化。
1 描述一种"发送"状态;此时,代码已经调用了XMLHttpRequest open()方法并且XMLHttpRequest已经准备好把一个请求发送到服务器。
2 描述一种"发送"状态;此时,已经通过send()方法把一个请求发送到服务器端,但是还没有收到一个响应。
3 描述一种"正在接收"状态;此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收结束。
4 描述一种"已加载"状态;此时,响应已经被完全接收。
onreadystatechange事件
无论readyState值何时发生改变,XMLHttpRequest对象都会激发一个readystatechange事件。其中,onreadystatechange属性接收一个EventListener值-向该方法指示无论readyState值何时发生改变,该对象都将激活。
responseText属性
这个responseText属性包含客户端接收到的HTTP响应的文本内容。当readyState值为0、1或2时,responseText包含一个空字符串。当readyState值为3(正在接收)时,响应中包含客户端还未完成的响应信息。当readyState为4(已加载)时,该responseText包含完整的响应信息。
responseXML属性
此responseXML属性用于当接收到完整的HTTP响应时(readyState为4)描述XML响应;此时,Content-Type头部指定MIME(媒体)类型为text/xml,application/xml或以+xml结尾。如果Content-Type头部并不包含这些媒体类型之一,那么responseXML的值为null。无论何时,只要readyState值不为4,那么该responseXML的值也为null。
其实,这个responseXML属性值是一个文档接口类型的对象,用来描述被分析的文档。如果文档不能被分析(例如,如果文档不是良构的或不支持文档相应的字符编码),那么responseXML的值将为null。
status属性
这个status属性描述了HTTP状态代码,而且其类型为short。而且,仅当readyState值为3(正在接收中)或4(已加载)时,这个status属性才可用。当readyState的值小于3时试图存取status的值将引发一个异常。
statusText属性
这个statusText属性描述了HTTP状态代码文本;并且仅当readyState值为3或4才可用。当readyState为其它值时试图存取statusText属性将引发一个异常。
三、 XMLHttpRequest对象的方法
XMLHttpRequest对象提供了各种方法用于初始化和处理HTTP请求,下列将逐个展开详细讨论。
abort()方法
你可以使用这个abort()方法来暂停与一个XMLHttpRequest对象相联系的HTTP请求,从而把该对象复位到未初始化状态。
open()方法
你需要调用open(DOMString method,DOMString uri,boolean async,DOMString username,DOMString password)方法初始化一个XMLHttpRequest对象。其中,method参数是必须提供的-用于指定你想用来发送请求的HTTP方法(GET,POST,PUT,Delete或HEAD)。为了把数据发送到服务器,应该使用POST方法;为了从服务器端检索数据,应该使用GET方法。另外,uri参数用于指定XMLHttpRequest对象把请求发送到的服务器相应的URI。借助于window.document.baseURI属性,该uri被解析为一个绝对的URI-换句话说,你可以使用相对的URI-它将使用与浏览器解析相对的URI一样的方式被解析。async参数指定是否请求是异步的-缺省值为true。为了发送一个同步请求,需要把这个参数设置为false。对于要求认证的服务器,你可以提供可选的用户名和口令参数。在调用open()方法后,XMLHttpRequest对象把它的readyState属性设置为1(打开)并且把responseText、responseXML、status和statusText属性复位到它们的初始值。另外,它还复位请求头部。注意,如果你调用open()方法并且此时readyState为4,则XMLHttpRequest对象将复位这些值。
send()方法
在通过调用open()方法准备好一个请求之后,你需要把该请求发送到服务器。仅当readyState值为1时,你才可以调用send()方法;否则的话,XMLHttpRequest对象将引发一个异常。该请求被使用提供给open()方法的参数发送到服务器。当async参数为true时,send()方法立即返回,从而允许其它客户端脚本处理继续。在调用send()方法后,XMLHttpRequest对象把readyState的值设置为2(发送)。当服务器响应时,在接收消息体之前,如果存在任何消息体的话,XMLHttpRequest对象将把readyState设置为3(正在接收中)。当请求完成加载时,它把readyState设置为4(已加载)。对于一个HEAD类型的请求,它将在把readyState值设置为3后再立即把它设置为4。
send()方法使用一个可选的参数-该参数可以包含可变类型的数据。典型地,你使用它并通过POST方法把数据发送到服务器。另外,你可以显式地使用null参数调用send()方法,这与不用参数调用它一样。对于大多数其它的数据类型,在调用send()方法之前,应该使用setRequestHeader()方法(见后面的解释)先设置Content-Type头部。如果在send(data)方法中的data参数的类型为DOMString,那么,数据将被编码为UTF-8。如果数据是Document类型,那么将使用由data.xmlEncoding指定的编码串行化该数据。
setRequestHeader()方法
该setRequestHeader(DOMString header,DOMString value)方法用来设置请求的头部信息。当readyState值为1时,你可以在调用open()方法后调用这个方法;否则,你将得到一个异常。
getResponseHeader()方法
getResponseHeader(DOMString header,value)方法用于检索响应的头部值。仅当readyState值是3或4(换句话说,在响应头部可用以后)时,才可以调用这个方法;否则,该方法返回一个空字符串。
getAllResponseHeaders()方法
该getAllResponseHeaders()方法以一个字符串形式返回所有的响应头部(每一个头部占单独的一行)。如果readyState的值不是3或4,则该方法返回null。
四、 发送请求
在AJAX中,许多使用XMLHttpRequest的请求都是从一个HTML事件(例如一个调用JavaScript函数的按钮点击(onclick)或一个按键(onkeypress))中被初始化的。AJAX支持包括表单校验在内的各种应用程序。有时,在填充表单的其它内容之前要求校验一个唯一的表单域。例如要求使用一个唯一的UserID来注册表单。如果不是使用AJAX技术来校验这个UserID域,那么整个表单都必须被填充和提交。如果该UserID不是有效的,这个表单必须被重新提交。例如,一个相应于一个要求必须在服务器端进行校验的Catalog ID的表单域可能按下列形式指定:
<form name="validationForm" action="validateForm" method="post">
<table>
<tr><td>Catalog Id:</td>
<td>
<input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()">
</td>
<td><div id="validationMessage"></div></td>
</tr>
</table></form>
前面的HTML使用validationMessage div来显示相应于这个输入域Catalog Id的一个校验消息。onkeyup事件调用一个JavaScript sendRequest()函数。这个sendRequest()函数创建一个XMLHttpRequest对象。创建一个XMLHttpRequest对象的过程因浏览器实现的不同而有所区别。如果浏览器支持XMLHttpRequest对象作为一个窗口属性(所有普通的浏览器都是这样的,除了IE 5和IE 6之外),那么,代码可以调用XMLHttpRequest的构造器。如果浏览器把XMLHttpRequest对象实现为一个ActiveXObject对象(就象在IE 5和IE 6中一样),那么,代码可以使用ActiveXObject的构造器。下面的函数将调用一个init()函数,它负责检查并决定要使用的适当的创建方法-在创建和返回对象之前。
<script type="text/javascript">
function sendRequest(){
var xmlHttpReq=init();
function init(){
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
</script>
接下来,你需要使用Open()方法初始化XMLHttpRequest对象-指定HTTP方法和要使用的服务器URL。
var catalogId=encodeURIComponent(document.getElementById("catalogId").value);
xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true);
默认情况下,使用XMLHttpRequest发送的HTTP请求是异步进行的,但是你可以显式地把async参数设置为true,如上面所展示的。
在这种情况下,对URL validateForm的调用将激活服务器端的一个servlet,但是你应该能够注意到服务器端技术不是根本性的;实际上,该URL可能是一个ASP,ASP.NET或PHP页面或一个Web服务-这无关紧要,只要该页面能够返回一个响应-指示CatalogID值是否是有效的-即可。因为你在作一个异步调用,所以你需要注册一个XMLHttpRequest对象将调用的回调事件处理器-当它的readyState值改变时调用。记住,readyState值的改变将会激发一个readystatechange事件。你可以使用onreadystatechange属性来注册该回调事件处理器。
xmlHttpReq.onreadystatechange=processRequest;
然后,我们需要使用send()方法发送该请求。因为这个请求使用的是HTTP GET方法,所以,你可以在不指定参数或使用null参数的情况下调用send()方法。
xmlHttpReq.send(null);
五、 处理请求
在这个示例中,因为HTTP方法是GET,所以在服务器端的接收servlet将调用一个doGet()方法,该方法将检索在URL中指定的catalogId参数值,并且从一个数据库中检查它的有效性。
本文示例中的这个servlet需要构造一个发送到客户端的响应;而且,这个示例返回的是XML类型,因此,它把响应的HTTP内容类型设置为text/xml并且把Cache-Control头部设置为no-cache。设置Cache-Control头部可以阻止浏览器简单地从缓存中重载页面。
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
...
...
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
}
来自于服务器端的响应是一个XML DOM对象,此对象将创建一个XML字符串-其中包含要在客户端进行处理的指令。另外,该XML字符串必须有一个根元素。
out.println("<catalogId>valid</catalogId>");
【注意】XMLHttpRequest对象的设计目的是为了处理由普通文本或XML组成的响应;但是,一个响应也可能是另外一种类型,如果用户代理(UA)支持这种内容类型的话。
当请求状态改变时,XMLHttpRequest对象调用使用onreadystatechange注册的事件处理器。因此,在处理该响应之前,你的事件处理器应该首先检查readyState的值和HTTP状态。当请求完成加载(readyState值为4)并且响应已经完成(HTTP状态为"OK")时,你就可以调用一个JavaScript函数来处理该响应内容。下列脚本负责在响应完成时检查相应的值并调用一个processResponse()方法。
function processRequest(){
if(xmlHttpReq.readyState==4){
if(xmlHttpReq.status==200){
processResponse();
}
}
}
该processResponse()方法使用XMLHttpRequest对象的responseXML和responseText属性来检索HTTP响应。如上面所解释的,仅当在响应的媒体类型是text/xml,application/xml或以+xml结尾时,这个responseXML才可用。这个responseText属性将以普通文本形式返回响应。对于一个XML响应,你将按如下方式检索内容:
var msg=xmlHttpReq.responseXML;
借助于存储在msg变量中的XML,你可以使用DOM方法getElementsByTagName()来检索该元素的值:
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;
最后,通过更新Web页面的validationMessage div中的HTML内容并借助于innerHTML属性,你可以测试该元素值以创建一个要显示的消息:
if(catalogId=="valid"){
var validationMessage = document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is Valid";
}
else
{
var validationMessage = document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is not Valid";
}
六、 小结
上面就是XMLHttpRequest对象使用的所有细节实现。通过不必把Web页面寄送到服务器而实现数据传送,XMLHttpRequest对象为客户端与服务器之间提供了一种动态的交互能力。你可以使用JavaScript启动一个请求并处理相应的返回值,然后使用浏览器的DOM方法更新页面中的数据。
一、 引言
异步JavaScript与XML(AJAX)是一个专用术语,用于实现在客户端脚本与服务器之间的数据交互过程。这一技术的优点在于,它向开发者提供了一种从Web服务器检索数据而不必把用户当前正在观察的页面回馈给服务器。与现代浏览器的通过存取浏览器DOM结构的编程代码(JavaScript)动态地改变被显示内容的支持相配合,AJAX让开发者在浏览器端更新被显示的HTML内容而不必刷新页面。换句话说,AJAX可以使基于浏览器的应用程序更具交互性而且更类似传统型桌面应用程序。
Google的Gmail和Outlook Express就是两个使用AJAX技术的我们所熟悉的例子。而且,AJAX可以用于任何客户端脚本语言中,这包括JavaScript,Jscript和VBScript。
AJAX利用一个构建到所有现代浏览器内部的对象-XMLHttpRequest-来实现发送和接收HTTP请求与响应信息。一个经由XMLHttpRequest对象发送的HTTP请求并不要求页面中拥有或回寄一个<form>元素。AJAX中的"A"代表了"异步",这意味着XMLHttpRequest对象的send()方法可以立即返回,从而让Web页面上的其它HTML/JavaScript继续其浏览器端处理而由服务器处理HTTP请求并发送响应。尽管缺省情况下请求是异步进行的,但是,你可以选择发送同步请求,这将会暂停其它Web页面的处理,直到该页面接收到服务器的响应为止。
微软在其Internet Explorer(IE) 5中作为一个ActiveX对象形式引入了XMLHttpRequest对象。其他的认识到这一对象重要性的浏览器制造商也都纷纷在他们的浏览器内实现了XMLHttpRequest对象,但是作为一个本地JavaScript对象而不是作为一个ActiveX对象实现。而如今,在认识到实现这一类型的价值及安全性特征之后,微软已经在其IE 7中把XMLHttpRequest实现为一个窗口对象属性。幸运的是,尽管其实现(因而也影响到调用方式)细节不同,但是,所有的浏览器实现都具有类似的功能,并且实质上是相同方法。目前,W3C组织正在努力进行XMLHttpRequest对象的标准化,并且已经发行了有关该W3C规范的一个草案。
本文将对XMLHttpRequest对象API进行详细讨论,并将解释其所有的属性和方法。
二、 XMLHttpRequest对象的属性和事件
XMLHttpRequest对象暴露各种属性、方法和事件以便于脚本处理和控制HTTP请求与响应。下面,我们将对此展开详细的讨论。
readyState属性
当XMLHttpRequest对象把一个HTTP请求发送到服务器时将经历若干种状态:一直等待直到请求被处理;然后,它才接收一个响应。这样以来,脚本才正确响应各种状态-XMLHttpRequest对象暴露一个描述对象的当前状态的readyState属性,如表格1所示。
表格1.XMLHttpRequest对象的ReadyState属性值列表。
ReadyState取值 描述
0 描述一种"未初始化"状态;此时,已经创建一个XMLHttpRequest对象,但是还没有初始化。
1 描述一种"发送"状态;此时,代码已经调用了XMLHttpRequest open()方法并且XMLHttpRequest已经准备好把一个请求发送到服务器。
2 描述一种"发送"状态;此时,已经通过send()方法把一个请求发送到服务器端,但是还没有收到一个响应。
3 描述一种"正在接收"状态;此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收结束。
4 描述一种"已加载"状态;此时,响应已经被完全接收。
onreadystatechange事件
无论readyState值何时发生改变,XMLHttpRequest对象都会激发一个readystatechange事件。其中,onreadystatechange属性接收一个EventListener值-向该方法指示无论readyState值何时发生改变,该对象都将激活。
responseText属性
这个responseText属性包含客户端接收到的HTTP响应的文本内容。当readyState值为0、1或2时,responseText包含一个空字符串。当readyState值为3(正在接收)时,响应中包含客户端还未完成的响应信息。当readyState为4(已加载)时,该responseText包含完整的响应信息。
responseXML属性
此responseXML属性用于当接收到完整的HTTP响应时(readyState为4)描述XML响应;此时,Content-Type头部指定MIME(媒体)类型为text/xml,application/xml或以+xml结尾。如果Content-Type头部并不包含这些媒体类型之一,那么responseXML的值为null。无论何时,只要readyState值不为4,那么该responseXML的值也为null。
其实,这个responseXML属性值是一个文档接口类型的对象,用来描述被分析的文档。如果文档不能被分析(例如,如果文档不是良构的或不支持文档相应的字符编码),那么responseXML的值将为null。
status属性
这个status属性描述了HTTP状态代码,而且其类型为short。而且,仅当readyState值为3(正在接收中)或4(已加载)时,这个status属性才可用。当readyState的值小于3时试图存取status的值将引发一个异常。
statusText属性
这个statusText属性描述了HTTP状态代码文本;并且仅当readyState值为3或4才可用。当readyState为其它值时试图存取statusText属性将引发一个异常。
三、 XMLHttpRequest对象的方法
XMLHttpRequest对象提供了各种方法用于初始化和处理HTTP请求,下列将逐个展开详细讨论。
abort()方法
你可以使用这个abort()方法来暂停与一个XMLHttpRequest对象相联系的HTTP请求,从而把该对象复位到未初始化状态。
open()方法
你需要调用open(DOMString method,DOMString uri,boolean async,DOMString username,DOMString password)方法初始化一个XMLHttpRequest对象。其中,method参数是必须提供的-用于指定你想用来发送请求的HTTP方法(GET,POST,PUT,Delete或HEAD)。为了把数据发送到服务器,应该使用POST方法;为了从服务器端检索数据,应该使用GET方法。另外,uri参数用于指定XMLHttpRequest对象把请求发送到的服务器相应的URI。借助于window.document.baseURI属性,该uri被解析为一个绝对的URI-换句话说,你可以使用相对的URI-它将使用与浏览器解析相对的URI一样的方式被解析。async参数指定是否请求是异步的-缺省值为true。为了发送一个同步请求,需要把这个参数设置为false。对于要求认证的服务器,你可以提供可选的用户名和口令参数。在调用open()方法后,XMLHttpRequest对象把它的readyState属性设置为1(打开)并且把responseText、responseXML、status和statusText属性复位到它们的初始值。另外,它还复位请求头部。注意,如果你调用open()方法并且此时readyState为4,则XMLHttpRequest对象将复位这些值。
send()方法
在通过调用open()方法准备好一个请求之后,你需要把该请求发送到服务器。仅当readyState值为1时,你才可以调用send()方法;否则的话,XMLHttpRequest对象将引发一个异常。该请求被使用提供给open()方法的参数发送到服务器。当async参数为true时,send()方法立即返回,从而允许其它客户端脚本处理继续。在调用send()方法后,XMLHttpRequest对象把readyState的值设置为2(发送)。当服务器响应时,在接收消息体之前,如果存在任何消息体的话,XMLHttpRequest对象将把readyState设置为3(正在接收中)。当请求完成加载时,它把readyState设置为4(已加载)。对于一个HEAD类型的请求,它将在把readyState值设置为3后再立即把它设置为4。
send()方法使用一个可选的参数-该参数可以包含可变类型的数据。典型地,你使用它并通过POST方法把数据发送到服务器。另外,你可以显式地使用null参数调用send()方法,这与不用参数调用它一样。对于大多数其它的数据类型,在调用send()方法之前,应该使用setRequestHeader()方法(见后面的解释)先设置Content-Type头部。如果在send(data)方法中的data参数的类型为DOMString,那么,数据将被编码为UTF-8。如果数据是Document类型,那么将使用由data.xmlEncoding指定的编码串行化该数据。
setRequestHeader()方法
该setRequestHeader(DOMString header,DOMString value)方法用来设置请求的头部信息。当readyState值为1时,你可以在调用open()方法后调用这个方法;否则,你将得到一个异常。
getResponseHeader()方法
getResponseHeader(DOMString header,value)方法用于检索响应的头部值。仅当readyState值是3或4(换句话说,在响应头部可用以后)时,才可以调用这个方法;否则,该方法返回一个空字符串。
getAllResponseHeaders()方法
该getAllResponseHeaders()方法以一个字符串形式返回所有的响应头部(每一个头部占单独的一行)。如果readyState的值不是3或4,则该方法返回null。
四、 发送请求
在AJAX中,许多使用XMLHttpRequest的请求都是从一个HTML事件(例如一个调用JavaScript函数的按钮点击(onclick)或一个按键(onkeypress))中被初始化的。AJAX支持包括表单校验在内的各种应用程序。有时,在填充表单的其它内容之前要求校验一个唯一的表单域。例如要求使用一个唯一的UserID来注册表单。如果不是使用AJAX技术来校验这个UserID域,那么整个表单都必须被填充和提交。如果该UserID不是有效的,这个表单必须被重新提交。例如,一个相应于一个要求必须在服务器端进行校验的Catalog ID的表单域可能按下列形式指定:
<form name="validationForm" action="validateForm" method="post">
<table>
<tr><td>Catalog Id:</td>
<td>
<input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()">
</td>
<td><div id="validationMessage"></div></td>
</tr>
</table></form>
前面的HTML使用validationMessage div来显示相应于这个输入域Catalog Id的一个校验消息。onkeyup事件调用一个JavaScript sendRequest()函数。这个sendRequest()函数创建一个XMLHttpRequest对象。创建一个XMLHttpRequest对象的过程因浏览器实现的不同而有所区别。如果浏览器支持XMLHttpRequest对象作为一个窗口属性(所有普通的浏览器都是这样的,除了IE 5和IE 6之外),那么,代码可以调用XMLHttpRequest的构造器。如果浏览器把XMLHttpRequest对象实现为一个ActiveXObject对象(就象在IE 5和IE 6中一样),那么,代码可以使用ActiveXObject的构造器。下面的函数将调用一个init()函数,它负责检查并决定要使用的适当的创建方法-在创建和返回对象之前。
<script type="text/javascript">
function sendRequest(){
var xmlHttpReq=init();
function init(){
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
</script>
接下来,你需要使用Open()方法初始化XMLHttpRequest对象-指定HTTP方法和要使用的服务器URL。
var catalogId=encodeURIComponent(document.getElementById("catalogId").value);
xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true);
默认情况下,使用XMLHttpRequest发送的HTTP请求是异步进行的,但是你可以显式地把async参数设置为true,如上面所展示的。
在这种情况下,对URL validateForm的调用将激活服务器端的一个servlet,但是你应该能够注意到服务器端技术不是根本性的;实际上,该URL可能是一个ASP,ASP.NET或PHP页面或一个Web服务-这无关紧要,只要该页面能够返回一个响应-指示CatalogID值是否是有效的-即可。因为你在作一个异步调用,所以你需要注册一个XMLHttpRequest对象将调用的回调事件处理器-当它的readyState值改变时调用。记住,readyState值的改变将会激发一个readystatechange事件。你可以使用onreadystatechange属性来注册该回调事件处理器。
xmlHttpReq.onreadystatechange=processRequest;
然后,我们需要使用send()方法发送该请求。因为这个请求使用的是HTTP GET方法,所以,你可以在不指定参数或使用null参数的情况下调用send()方法。
xmlHttpReq.send(null);
五、 处理请求
在这个示例中,因为HTTP方法是GET,所以在服务器端的接收servlet将调用一个doGet()方法,该方法将检索在URL中指定的catalogId参数值,并且从一个数据库中检查它的有效性。
本文示例中的这个servlet需要构造一个发送到客户端的响应;而且,这个示例返回的是XML类型,因此,它把响应的HTTP内容类型设置为text/xml并且把Cache-Control头部设置为no-cache。设置Cache-Control头部可以阻止浏览器简单地从缓存中重载页面。
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
...
...
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
}
来自于服务器端的响应是一个XML DOM对象,此对象将创建一个XML字符串-其中包含要在客户端进行处理的指令。另外,该XML字符串必须有一个根元素。
out.println("<catalogId>valid</catalogId>");
【注意】XMLHttpRequest对象的设计目的是为了处理由普通文本或XML组成的响应;但是,一个响应也可能是另外一种类型,如果用户代理(UA)支持这种内容类型的话。
当请求状态改变时,XMLHttpRequest对象调用使用onreadystatechange注册的事件处理器。因此,在处理该响应之前,你的事件处理器应该首先检查readyState的值和HTTP状态。当请求完成加载(readyState值为4)并且响应已经完成(HTTP状态为"OK")时,你就可以调用一个JavaScript函数来处理该响应内容。下列脚本负责在响应完成时检查相应的值并调用一个processResponse()方法。
function processRequest(){
if(xmlHttpReq.readyState==4){
if(xmlHttpReq.status==200){
processResponse();
}
}
}
该processResponse()方法使用XMLHttpRequest对象的responseXML和responseText属性来检索HTTP响应。如上面所解释的,仅当在响应的媒体类型是text/xml,application/xml或以+xml结尾时,这个responseXML才可用。这个responseText属性将以普通文本形式返回响应。对于一个XML响应,你将按如下方式检索内容:
var msg=xmlHttpReq.responseXML;
借助于存储在msg变量中的XML,你可以使用DOM方法getElementsByTagName()来检索该元素的值:
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;
最后,通过更新Web页面的validationMessage div中的HTML内容并借助于innerHTML属性,你可以测试该元素值以创建一个要显示的消息:
if(catalogId=="valid"){
var validationMessage = document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is Valid";
}
else
{
var validationMessage = document.getElementById("validationMessage");
validationMessage.innerHTML = "Catalog Id is not Valid";
}
六、 小结
上面就是XMLHttpRequest对象使用的所有细节实现。通过不必把Web页面寄送到服务器而实现数据传送,XMLHttpRequest对象为客户端与服务器之间提供了一种动态的交互能力。你可以使用JavaScript启动一个请求并处理相应的返回值,然后使用浏览器的DOM方法更新页面中的数据。
Dec
20
最近,在搞这个东西,网上也找不到asp相关的,如果有人很早弄出来了,也不要笑话偶;费了好久,总算搞定;
原理:用stream对象预读文件的头两个字节,分析判断出utf-8,unicode,ANSI(简体中文操作系统,即gb2312)编码
相关资料:
ANSI: 无格式定义;
Unicode: 前两个字节为FFFE;
Unicode big endian: 前两字节为FEFF;
UTF-8: 前两字节为EFBB;
function checkcode(path)
set objstream=server.createobject("adodb.stream")
objstream.Type=1
objstream.mode=3
objstream.open
objstream.Position=0
objstream.loadfromfile path
bintou=objstream.read(2)
If AscB(MidB(bintou,1,1))=&HEF And AscB(MidB(bintou,2,1))=&HBB Then
checkcoder="utf-8"
ElseIf AscB(MidB(bintou,1,1))=&HFF And AscB(MidB(bintou,2,1))=&HFE Then
checkcode="unicode"
Else
checkcode="gb2312"
End If
objstream.close
set objstream=nothing
end function
补充:
谢小雨提醒,先前的简直是胡扯;ANSI的本地编码,都是各国自己定义的,没有固定的文件头格式,在大陆中文操作系统下,是可读的gb2312,在其他语言的系统下,就是乱码,所以这部分没必要再详细区分
得到文件编码,stream流就能按照需要的编码打开,就不会乱码了
原理:用stream对象预读文件的头两个字节,分析判断出utf-8,unicode,ANSI(简体中文操作系统,即gb2312)编码
相关资料:
ANSI: 无格式定义;
Unicode: 前两个字节为FFFE;
Unicode big endian: 前两字节为FEFF;
UTF-8: 前两字节为EFBB;
function checkcode(path)
set objstream=server.createobject("adodb.stream")
objstream.Type=1
objstream.mode=3
objstream.open
objstream.Position=0
objstream.loadfromfile path
bintou=objstream.read(2)
If AscB(MidB(bintou,1,1))=&HEF And AscB(MidB(bintou,2,1))=&HBB Then
checkcoder="utf-8"
ElseIf AscB(MidB(bintou,1,1))=&HFF And AscB(MidB(bintou,2,1))=&HFE Then
checkcode="unicode"
Else
checkcode="gb2312"
End If
objstream.close
set objstream=nothing
end function
补充:
谢小雨提醒,先前的简直是胡扯;ANSI的本地编码,都是各国自己定义的,没有固定的文件头格式,在大陆中文操作系统下,是可读的gb2312,在其他语言的系统下,就是乱码,所以这部分没必要再详细区分
得到文件编码,stream流就能按照需要的编码打开,就不会乱码了
Dec
16
一、前言
ASP (Active Server Pages) 是服务器端的脚本编写环境,它由微软公司的IIS3.0以上版本支持。它可用来创建动态 Web 页或生成功能强大的 Web应用程序。ASP页是包括 HTML 标记、文本和脚本命令的文件。ASP页可调用ActiveX组件来执行任务,例如连接到数据库或进行商务计算。通过ASP,可为您的Web页添加交互内容或用HTML页构成整个Web应用程序,这些应用程序使用HTML页作为您的客户的界面。
二、ASP模型
浏览器从Web服务器上请求 .asp文件时,ASP 脚本开始运行。然后Web服务器调用ASP,ASP全面读取请求的文件,执行所有脚本命令,并将Web页传送给浏览器。
ASP提供了一个在HTML页中使用现有脚本语言如 Microsoft VBScript 和 Microsoft JScript 的框架。
ASP提供内建对象,这些对象使用户更容易收集通过浏览器请求发送的信息、响应浏览器以及存储用户信息。包括Application、Request、Response、Server、Session 和ObjectContext 对象。其中最为常用的为Request、Response 和Server三个对象,它们分别用于从浏览器请求信息、向浏览器发送信息和访问服务器上对象的属性和方法。
三、ADO
ASP和后台数据库连接使用微软的ADO(ActiveX Data Objects),ADO是一项容易使用并且可扩展的将数据库访问添加到Web页的技术。可以使用ADO去编写紧凑简明的脚本以便连接到Open Database Connectivity(ODBC)兼容的数据库和 OLE DB兼容的数据源。
ADO包含7个内置对象,它们分别为Connection、Command、RecordSet、Fields、Error、Parameters和Properties。通过这些对象,ASP可以完成对后台数据库的所有操作。
四、ASP调用视图和存储过程
在一般的MIS应用中,会有大量的报表,此时我们可以在后台数据库编写相应的视图或存储过程,用ASP通过ADO调用以完成报表工作。下面用一个例子说明相应的操作过程。
1.创建 ODBC DSN 文件
在创建数据库脚本之前,必须提供一条使ADO定位、标识和与数据库通讯的途径。数据库驱动程序使用Data Source Name (DSN) 定位和标识特定的ODBC兼容数据库,将信息从 Web 应用程序传递给数据库。
2. 调用数据库视图
访问数据库信息的第一步是和数据库源建立连接。ADO提供Connection对象,可以使用该对象建立和管理应用程序和 ODBC数据库之间的连接。
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;
UID=sa;PWD=;APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
Set cmdTemp = Server.CreateObject("ADODB.Command") '建立命令对象
Set rst= Server.CreateObject("ADODB.Recordset") '建立记录集对象
cmdTemp.CommandText = "Customers "
cmdTemp.CommandType = 2
Set cmdTemp.ActiveConnection = DataConn
rst.Open cmdTemp, , 1, 3 '生成查询结果
%>
此时,Customers为视图,从视图中查询数据与从基表中查询数据的方法是相同的。
3.调用数据库存储过程
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;UID=sa;
PWD=;APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
Set cmdTemp = Server.CreateObject("ADODB.Command") '建立命令对象
Set rst = Server.CreateObject("ADODB.Recordset") '建立记录集对象
cmdTemp.CommandText = "dbo.pd_test" '存储过程名称
cmdTemp.CommandType = 4 '命令类别为4,表示为存储过程
Set cmdTemp.ActiveConnection = Dataconn
Set tmpParam = cmdTemp.CreateParameter("Return Value", 3, 4, 4)
cmdTemp.Parameters.Append tmpParam
Set tmpParam = cmdTemp.CreateParameter("@BeginDate", 135, 1, 16, riqi)
'创建输入参数对象
cmdTemp.Parameters.Append tmpParam
rst.Open cmdTemp, , 1, 3 '生成查询结果
%>
这里调用的存储过程为pd_test,这种是ADO中提供的标准方法,但存在一个问题,就是当在存储过程中有两个以上的Select语句,但从逻辑上又不可能同时执行的时候,ADO会提示你存储过程中Select语句太多,解决方法是直接用ADO的CONNECTION对象的EXECUTE方法直接执行存储过程,如下:
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;UID=sa;PWD=;
APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
ss = "EXECUTE dbo.pd_test " & "'" & riqi1 & "'"
Set rs = dataconn.Execute(ss)
%>
有关ASP和ADO使用的详细信息,请参阅 Microsoft ActiveX Data Objects (ADO) 和Active Server Pages(ASP)的详细参考。
五、结束语
在B/S结构的开发中,我们可以把一些商业规则或复杂查询用存储过程在DBMS中编写,然后用ASP中的ADO对象调用,完成原来C/S结构中的传统功能。
ASP (Active Server Pages) 是服务器端的脚本编写环境,它由微软公司的IIS3.0以上版本支持。它可用来创建动态 Web 页或生成功能强大的 Web应用程序。ASP页是包括 HTML 标记、文本和脚本命令的文件。ASP页可调用ActiveX组件来执行任务,例如连接到数据库或进行商务计算。通过ASP,可为您的Web页添加交互内容或用HTML页构成整个Web应用程序,这些应用程序使用HTML页作为您的客户的界面。
二、ASP模型
浏览器从Web服务器上请求 .asp文件时,ASP 脚本开始运行。然后Web服务器调用ASP,ASP全面读取请求的文件,执行所有脚本命令,并将Web页传送给浏览器。
ASP提供了一个在HTML页中使用现有脚本语言如 Microsoft VBScript 和 Microsoft JScript 的框架。
ASP提供内建对象,这些对象使用户更容易收集通过浏览器请求发送的信息、响应浏览器以及存储用户信息。包括Application、Request、Response、Server、Session 和ObjectContext 对象。其中最为常用的为Request、Response 和Server三个对象,它们分别用于从浏览器请求信息、向浏览器发送信息和访问服务器上对象的属性和方法。
三、ADO
ASP和后台数据库连接使用微软的ADO(ActiveX Data Objects),ADO是一项容易使用并且可扩展的将数据库访问添加到Web页的技术。可以使用ADO去编写紧凑简明的脚本以便连接到Open Database Connectivity(ODBC)兼容的数据库和 OLE DB兼容的数据源。
ADO包含7个内置对象,它们分别为Connection、Command、RecordSet、Fields、Error、Parameters和Properties。通过这些对象,ASP可以完成对后台数据库的所有操作。
四、ASP调用视图和存储过程
在一般的MIS应用中,会有大量的报表,此时我们可以在后台数据库编写相应的视图或存储过程,用ASP通过ADO调用以完成报表工作。下面用一个例子说明相应的操作过程。
1.创建 ODBC DSN 文件
在创建数据库脚本之前,必须提供一条使ADO定位、标识和与数据库通讯的途径。数据库驱动程序使用Data Source Name (DSN) 定位和标识特定的ODBC兼容数据库,将信息从 Web 应用程序传递给数据库。
2. 调用数据库视图
访问数据库信息的第一步是和数据库源建立连接。ADO提供Connection对象,可以使用该对象建立和管理应用程序和 ODBC数据库之间的连接。
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;
UID=sa;PWD=;APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
Set cmdTemp = Server.CreateObject("ADODB.Command") '建立命令对象
Set rst= Server.CreateObject("ADODB.Recordset") '建立记录集对象
cmdTemp.CommandText = "Customers "
cmdTemp.CommandType = 2
Set cmdTemp.ActiveConnection = DataConn
rst.Open cmdTemp, , 1, 3 '生成查询结果
%>
此时,Customers为视图,从视图中查询数据与从基表中查询数据的方法是相同的。
3.调用数据库存储过程
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;UID=sa;
PWD=;APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
Set cmdTemp = Server.CreateObject("ADODB.Command") '建立命令对象
Set rst = Server.CreateObject("ADODB.Recordset") '建立记录集对象
cmdTemp.CommandText = "dbo.pd_test" '存储过程名称
cmdTemp.CommandType = 4 '命令类别为4,表示为存储过程
Set cmdTemp.ActiveConnection = Dataconn
Set tmpParam = cmdTemp.CreateParameter("Return Value", 3, 4, 4)
cmdTemp.Parameters.Append tmpParam
Set tmpParam = cmdTemp.CreateParameter("@BeginDate", 135, 1, 16, riqi)
'创建输入参数对象
cmdTemp.Parameters.Append tmpParam
rst.Open cmdTemp, , 1, 3 '生成查询结果
%>
这里调用的存储过程为pd_test,这种是ADO中提供的标准方法,但存在一个问题,就是当在存储过程中有两个以上的Select语句,但从逻辑上又不可能同时执行的时候,ADO会提示你存储过程中Select语句太多,解决方法是直接用ADO的CONNECTION对象的EXECUTE方法直接执行存储过程,如下:
<%
Set Dataconn = Server.CreateObject("ADODB.Connection") '建立连接对象
Dataconn.Open "DSN=SinoTrans;SERVER=APP_SERVER;UID=sa;PWD=;
APP=Microsoft (R) Developer Studio;WSID=APP_SERVER;Regional=Yes"
ss = "EXECUTE dbo.pd_test " & "'" & riqi1 & "'"
Set rs = dataconn.Execute(ss)
%>
有关ASP和ADO使用的详细信息,请参阅 Microsoft ActiveX Data Objects (ADO) 和Active Server Pages(ASP)的详细参考。
五、结束语
在B/S结构的开发中,我们可以把一些商业规则或复杂查询用存储过程在DBMS中编写,然后用ASP中的ADO对象调用,完成原来C/S结构中的传统功能。
Dec
12

继《信息时报》爆出“网友建议央视改名中国国家电视台”的消息之后,央视可谓是烦心儿事一件接着一件:《新闻联播》“换人夭折”到2007年春晚导演惹非议,《梦想中国》身陷“毒舌门”到黄健翔世界杯解说词风波,“青歌赛”毁誉参半到中央一、二套与艺术人生深陷商标抢注尴尬境地……现在,历经转型阵痛的央视更是命运多舛,成为网友们狂轰乱炸的首选目标。前天,网民十三虎在抛出“央视十大烦心郁闷窝脖儿事”,“阿拉门”更是在博客中列举中央电视台十大罪状,再次把央视推到网络口水战的风口浪尖……
烦心事之①:深陷商标抢注漩涡
7月31日,网上爆出福建长乐市李先生已经申请“中央一套”商标注册的消息,涉及商品包括子宫帽、避孕套、非化学避孕用具等10种。紧接着8月,再爆出南京王先生将中央二套抢注为内衣商标,而且还为自己申请注册的“中央二套”内衣商标设计广告词:中央二套,美人衣靠。一时之间,央视电视频道名称频繁遭遇商标抢注的困挠,搞得央视不知如何应对,尴尬不已。
烦心事之②:春节晚会渐成鸡肋
如今,春晚在百姓心目中业已成了“鸡肋”食之无味弃之可惜。而每年春晚有“三个确定”让央视甚为头痛,即——导演的确定、节目的确定,演员的确定。近些年来,央视春节晚会被观众戏谑地称作是“老太太过年,一年不如一年”。好的作品选不上,残次节目充斥晚会,弄得百姓骂声不绝,艺人怨声载道。曾经最早搞笑小品演员陈佩斯抨击春晚说:“它已经变成了一个名利场,一个权钱交易的地方”。而就央视而言,春晚不办不是,办也不是,央视自认为是猪八戒照镜子里外不是人儿,“春晚”这个烫手的山芋让央视脑筋伤透、心烦难诉。
烦心事之③:消极对待恶搞之风
今年青歌赛开赛前,央视“青歌赛”组委会曾邀请北京主流媒体出席第12届青年歌手大赛的策划座谈会,并在会上播放署名“胡倒戈”的网友制作的短片《闪闪的红星之潘冬子参赛记》。虽然,《闪闪的红星》出品方八一电影制片厂发出声明,称该短片恶搞红色经典,严厉谴责“恶搞”行为,而“青歌赛”组委会却在媒体面前播放,被网民认为是对恶搞的纵容。事后,央视表示将和八一厂一同坚决抵制恶搞,但其轻缓暖昧的态度,让人觉得有消极对待之感。网友评论说要论恶搞,央视堪称前辈,从曾在网上盛传的“改革在十月”可谓开了恶搞之先河。央视因此背上“屈从媚俗滑向堕落”的骂名。
烦心事之④:新闻联播换脸流产
长期以来,央视《新闻联播》一直保持着邢质斌、罗京等“老面孔”。6月5日,在央视新闻频道改版第一天,《世界周刊》主持康辉与《国际时讯》的主持李梓萌首次登上《新闻联播》主播台,但奇怪的是,6月6日的《新闻联播》中,观众依旧看到邢质斌的“老”脸,主要原因是李梓萌在播报一起灾难事件时,面露微笑表情,与内容相背的表现遭到网友质疑,《新闻联播》“换人改革”因此流产,让央视对《新闻联播》更换新人的信心备感底气不足,心烦哮喘自是难免。
烦心事之⑤:节目被指东施效颦
“砖客联盟”精英之一阿拉门板儿油质疑央视为保住行业老大的面子与地位,不惜通过行政手段,借广电总局的文件对某些强势地方卫星台进行批评甚至压制、缩少其发展空间,经常摆出“老大”架势,动不动给人家戴高帽,难逃“只许州官放火,不许百姓点灯”的嫌疑。最突出的例子就是对湖南卫视《超级女声》等节目进行挤压,而在批评他人的同时自己却“东施效颦”,推出《梦想中国》节目,曾一度让央视甚是头痛,大失面子。
烦心事之⑥:节目搞学者明星化
在“2006青年歌手大奖赛”中,评委余秋雨成为网友重点评论的人物。余秋雨的出现虽然给青歌赛增添了看点,但由于其略显啰嗦的点评,被网友质疑“喧宾夺主,秀文化,抢镜头”,口无遮拦的点评屡受抨击。而让“学者明星化”这一毁誉参半的帽子也扣在央视的头上(“学者明星化”现象还存在《百家讲坛》等节目),央视在为收视率猛增而偷着乐的同时,被网友如此棒喝,心头难免平添烦忧。
烦心事之⑦:德国世界杯解说门
北京时间6月27日凌晨,在德国世界杯八分之一决赛——意大利队VS澳大利亚队比赛中,意大利中后卫马特拉奇被罚下场的情况下,托蒂在下半场补时阶段点球绝杀澳大利亚队一刻,黄健翔声嘶力竭喊出系列令人惊心动魄的“心声”,其中最高昂最响亮的一句是:“意大利万岁”!为意大利队的晋级呐喊,黄健翔以不同往常的激情解说震撼中国球迷,在网上引发极大波澜,引发“倒黄”和“挺黄”的网络大战,至今让央视心有余悸。
烦心事之⑧:名牌主持“毒舌门”
央视名牌主持人李咏由于在《梦想中国》重庆站海选中,口无遮拦羞辱选手,在网上招至一片“倒咏”之声,“倒咏”阵势真是——嘴巴喧天,骂声齐鸣!甚至有人征集万人签名要李咏“下课”。“倒咏”声浪让李咏再无法在狂妄自傲的“荣誉之海”里自由自在的“泳(咏)”了!李咏被“倒”,央视跟着挨骂,央视名牌主持给央视丢了脸,个中烦恼只有央视自己清楚。
烦心事之⑨:百亿造媒体第一楼
耗资数十亿,欲建成“中国媒体第一楼”的央视新楼落址CBD一度在互联网引起强烈反响,后来传出因交通、成本、安全、政府宏观调控等问题,甚至还出现停工之说。去年9月,中央电视台新台址建设工程宣布正式开工,但造价翻番,从原来50亿上升到100亿,造价飙升的主要原因是抗地震烈度从7度上升到9度,如此巨大投入因此遭到质疑:央视需要能装250个频道的大楼吗?央视大楼就不能瘦瘦身?央视必须要用设计费惊人的“洋设计”吗?100亿“花”起来不是那么痛快。
烦心事之⑩:节目走低俗化
郭德刚要上2007春晚的消息被网友戏称“央视向低俗低头”!红得发紫的郭德刚在相声圈里人眼中却是不入流,对此郭德反唇相讥:我负责“说”相声,他们负责“品”相声!对于央视而言,不仅是春晚,各类节目是要抓住最火的“红人大腕”打收视牌,而因此遭如此奚落是央视始料未及,在高雅与通俗(两者达到统一实在不易)之间如何选择,正是央视深感郁闷之所在。
Dec
8
9月23日早晨,93岁的他静静地走了。无数活着的人在口口相传中记住了他——蹬三轮的老人白芳礼。这不是神话!这位老人在74岁以后的生命中,靠着一脚一脚地蹬三轮,挣下35万元人民币,捐给了天津的多所大学、中学和小学,资助了300多名贫困学生。而每一个走近他的人都惊异地发现,他的个人生活几近乞丐,他的私有财产账单上是一个零。
贴子相关图片:

从1993年到1998年,老人资助了红光中学的200多名藏族学生,月月给他们补助,直到他们高中毕业。
白芳礼倾尽所能地把他的光和热洒向了众多需要帮助的学生身上,学生们从他那里获得的感动和成长,让他收获了无上的幸福。
老人忘不了那一年他到南开大学给贫困学生捐款的一幕。当时,学校要派车去接他,他说不用了,把省下的汽油钱给穷孩子买书。他自个儿蹬三轮到了学校。捐赠仪式上,老师把这个事一讲,台下一片哭声。许多学生上台从老人那里接过资助的钱时,双手都在发抖。
一位来自新疆地区的贫困学生,功课优秀,没毕业就被天津一家大公司看中,拟以高薪聘用。这一天,他走上台激动地说:“我从白爷爷身上感到了一种前所未有的精神和力量。我正式向学校、也向白爷爷表示:毕业后我不留天津,要回到目前还贫困的家乡,以白爷爷的精神去为改变家乡面貌做贡献!”他深深地向白芳礼老人鞠了一躬。全场掌声雷动。老人高兴得流下了眼泪。
事后,老人对他的老友说:“我过得是苦,挣来的每一块钱都不容易。可我心里是舒畅的。看到大学生们能从我做的这一点点小事上唤起一份报国心,我高兴啊!”
这些年得到白芳礼捐助的大学、中学、小学以及教育基金等单位达30家之多。老人捐钱从不图回报,许多得到他帮助的学生并不知道他的姓名。他的快乐和幸福来自他那一颗太阳的心!
白芳礼老人生前与受到他资助的天津市红光中学藏族学生在一起(1994年摄)。
贴子相关图片:

他坚守着自己心中的追求,就像战士坚守着战斗的高地
1994年,白芳礼81岁。这一天,他把整整一个寒冬挣来的3000元辛苦钱交给一所学校后,校领导说代表全校300名贫困生向他致敬。这话触动了他:现今缺钱上学的孩子这么多,光靠我一个人蹬三轮车挣来的钱救不了几个娃呀!
他琢磨了一夜,第二天一早就把儿女家的门敲开了:“我准备把你们妈和我留下的那两间老屋给卖了,再贷点款办个公司,赚钱支教。”
不多几天,在紧靠天津火车站的一块小地盘上,出现了一个7平方米的小售货亭,里面摆着一些糕点烟酒等,当头挂着一块牌子——“白芳礼支教公司”。他对受雇的员工宣布:“我们挣来的钱姓‘教育’,每月结算,月月上交。”
小售货亭让白芳礼增加了不少支教的财力,却一点也没有改变他蹬三轮的生活。他把售货亭交给伙计打理,自己照样天天出车拉活。他说:“我出一天车总能挣回二三十块钱,可以供十来个苦孩子一天的饭钱呢!”
为了在车站前拉活方便,他索性挨着亭子搭了个3平方米的小铁皮棚子,里面用砖头搭了一块木板算是“床”,棚顶上的接缝处露着一道道青天。夏天,棚里的温度高达40摄氏度;冬天,放杯水可以冻成冰坨子。白芳礼就在这里面住了整整5年。
“这老爷子怎么像个没家的人……”老人的儿女一直承受着某种误解的压力,他们对父亲有些埋怨。蹬着三轮闯荡了一辈子的白芳礼,骨子里有一种大义与胸怀,国家与社会在他心目中有头号的位置。他对儿女们说:“我现在是有国无家,为了能给孩子们多挣钱,累点苦点都没啥.
然而,终于在那一天他感到了无奈。1999年,天津火车站进行整顿,所有商亭一律被拆除。望着转眼工夫被拆成一堆垃圾的“白芳礼支教公司”,老人哭了。他老了,腿脚没劲了,以后还指望用什么挣钱给孩子们读书呢?
那年冬天,老人蜷缩在车站附近一个自行车棚里,硬是给人家看了3个月的自行车,每天把所得的1角、2角、1元、2元的钱整整齐齐地放在一个饭盒里,等存满500元时,他揣上饭盒,蹬上车,在一个飘着雪花的冬日,来到了天津耀华中学。人们看到,他的头发、胡子全白了,身上已经被雪浸湿。他向学校的老师递上饭盒里的500元钱,说了一句:“我干不动了,以后可能不能再捐了,这是我最后的一笔钱……”老师们全哭了。
白芳礼您的生日是父亲节 一生辛苦无人能忘
贴子相关图片:

一颗太阳的心是不会熄灭的,白芳礼依然活在他的追求中。其后的岁月里,他播洒下的阳光迸裂成一个更大的阳光的世界。
当白芳礼患病的消息传出,一批又一批学校的学生来到他的身边。他望着孩子们,泪水一个劲儿地流:“孩子们,等我病好了,我还要蹬三轮挣钱资助你们读书!”
然而,老人再也不能实现他的愿望了。他像流星一样划过,但却让自己燃烧着,给世界留下了最后的光芒……
贴子相关图片:

我给老爷爷鞠了躬再走!祝福!
走好
贴子相关图片:

都好好看看
贴子相关图片:
贴子相关图片:

从1993年到1998年,老人资助了红光中学的200多名藏族学生,月月给他们补助,直到他们高中毕业。
白芳礼倾尽所能地把他的光和热洒向了众多需要帮助的学生身上,学生们从他那里获得的感动和成长,让他收获了无上的幸福。
老人忘不了那一年他到南开大学给贫困学生捐款的一幕。当时,学校要派车去接他,他说不用了,把省下的汽油钱给穷孩子买书。他自个儿蹬三轮到了学校。捐赠仪式上,老师把这个事一讲,台下一片哭声。许多学生上台从老人那里接过资助的钱时,双手都在发抖。
一位来自新疆地区的贫困学生,功课优秀,没毕业就被天津一家大公司看中,拟以高薪聘用。这一天,他走上台激动地说:“我从白爷爷身上感到了一种前所未有的精神和力量。我正式向学校、也向白爷爷表示:毕业后我不留天津,要回到目前还贫困的家乡,以白爷爷的精神去为改变家乡面貌做贡献!”他深深地向白芳礼老人鞠了一躬。全场掌声雷动。老人高兴得流下了眼泪。
事后,老人对他的老友说:“我过得是苦,挣来的每一块钱都不容易。可我心里是舒畅的。看到大学生们能从我做的这一点点小事上唤起一份报国心,我高兴啊!”
这些年得到白芳礼捐助的大学、中学、小学以及教育基金等单位达30家之多。老人捐钱从不图回报,许多得到他帮助的学生并不知道他的姓名。他的快乐和幸福来自他那一颗太阳的心!
白芳礼老人生前与受到他资助的天津市红光中学藏族学生在一起(1994年摄)。
贴子相关图片:

他坚守着自己心中的追求,就像战士坚守着战斗的高地
1994年,白芳礼81岁。这一天,他把整整一个寒冬挣来的3000元辛苦钱交给一所学校后,校领导说代表全校300名贫困生向他致敬。这话触动了他:现今缺钱上学的孩子这么多,光靠我一个人蹬三轮车挣来的钱救不了几个娃呀!
他琢磨了一夜,第二天一早就把儿女家的门敲开了:“我准备把你们妈和我留下的那两间老屋给卖了,再贷点款办个公司,赚钱支教。”
不多几天,在紧靠天津火车站的一块小地盘上,出现了一个7平方米的小售货亭,里面摆着一些糕点烟酒等,当头挂着一块牌子——“白芳礼支教公司”。他对受雇的员工宣布:“我们挣来的钱姓‘教育’,每月结算,月月上交。”
小售货亭让白芳礼增加了不少支教的财力,却一点也没有改变他蹬三轮的生活。他把售货亭交给伙计打理,自己照样天天出车拉活。他说:“我出一天车总能挣回二三十块钱,可以供十来个苦孩子一天的饭钱呢!”
为了在车站前拉活方便,他索性挨着亭子搭了个3平方米的小铁皮棚子,里面用砖头搭了一块木板算是“床”,棚顶上的接缝处露着一道道青天。夏天,棚里的温度高达40摄氏度;冬天,放杯水可以冻成冰坨子。白芳礼就在这里面住了整整5年。
“这老爷子怎么像个没家的人……”老人的儿女一直承受着某种误解的压力,他们对父亲有些埋怨。蹬着三轮闯荡了一辈子的白芳礼,骨子里有一种大义与胸怀,国家与社会在他心目中有头号的位置。他对儿女们说:“我现在是有国无家,为了能给孩子们多挣钱,累点苦点都没啥.
然而,终于在那一天他感到了无奈。1999年,天津火车站进行整顿,所有商亭一律被拆除。望着转眼工夫被拆成一堆垃圾的“白芳礼支教公司”,老人哭了。他老了,腿脚没劲了,以后还指望用什么挣钱给孩子们读书呢?
那年冬天,老人蜷缩在车站附近一个自行车棚里,硬是给人家看了3个月的自行车,每天把所得的1角、2角、1元、2元的钱整整齐齐地放在一个饭盒里,等存满500元时,他揣上饭盒,蹬上车,在一个飘着雪花的冬日,来到了天津耀华中学。人们看到,他的头发、胡子全白了,身上已经被雪浸湿。他向学校的老师递上饭盒里的500元钱,说了一句:“我干不动了,以后可能不能再捐了,这是我最后的一笔钱……”老师们全哭了。
白芳礼您的生日是父亲节 一生辛苦无人能忘
贴子相关图片:

一颗太阳的心是不会熄灭的,白芳礼依然活在他的追求中。其后的岁月里,他播洒下的阳光迸裂成一个更大的阳光的世界。
当白芳礼患病的消息传出,一批又一批学校的学生来到他的身边。他望着孩子们,泪水一个劲儿地流:“孩子们,等我病好了,我还要蹬三轮挣钱资助你们读书!”
然而,老人再也不能实现他的愿望了。他像流星一样划过,但却让自己燃烧着,给世界留下了最后的光芒……
贴子相关图片:

我给老爷爷鞠了躬再走!祝福!
走好
贴子相关图片:

都好好看看
贴子相关图片:










