2006年08月08日

常用正则表代式集

匹配中文字符的正则表达式: [\u4e00-\u9fa5]

匹配双字节字符(包括汉字在内):[^\x00-\xff]

应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}

匹配空行的正则表达式:\n[\s| ]*\r

匹配HTML标记的正则表达式:/<(.*)>.*<\/\1>|<(.*) \/>/

匹配首尾空格的正则表达式:(^\s*)|(\s*$)

应用:javascript中没有像vbscript那样的trim函数,我们就可以利用这个表达式来实现,如下:

String.prototype.trim = function()
{
  return this.replace(/(^\s*)|(\s*$)/g, "");
}

利用正则表达式分解和转换IP地址:

下面是利用正则表达式匹配IP地址,并将IP地址转换成对应数值的Javascript程序:

function IP2V(ip)
{
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式
if(re.test(ip))
{
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1
}
else
{
throw new Error("Not a valid IP address!")
}
}

不过上面的程序如果不用正则表达式,而直接用split函数来分解可能更简单,程序如下:

var ip="10.100.20.168"
ip=ip.split(".")
alert("IP值是:"+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

匹配网址URL的正则表达式:http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?

利用正则表达式去除字串中重复的字符的算法程序:

var s="abacabefgeeii"
var s1=s.replace(/(.).*\1/g,"$1")
var re=new RegExp("["+s1+"]","g")
var s2=s.replace(re,"")
alert(s1+s2) //结果为:abcefgi

得用正则表达式从URL地址中提取文件名的javascript程序,如下结果为page1

s="http://www.9499.net/page1.htm"
s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2")
alert(s)

利用正则表达式限制网页表单里的文本框输入内容:

用正则表达式限制只能输入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,”)" onbeforepaste="clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^\u4E00-\u9FA5]/g,”))"

用正则表达式限制只能输入全角字符: onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,”)" onbeforepaste="clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^\uFF00-\uFFFF]/g,”))"

用正则表达式限制只能输入数字:onkeyup="value=value.replace(/[^\d]/g,”) "onbeforepaste="clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^\d]/g,”))"

用正则表达式限制只能输入数字和英文:onkeyup="value=value.replace(/[\W]/g,”) "onbeforepaste="clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^\d]/g,”))"

"^\d+$"  //非负整数(正整数 + 0)
"^[0-9]*[1-9][0-9]*$"  //正整数
"^((-\d+)|(0+))$"  //非正整数(负整数 + 0)
"^-[0-9]*[1-9][0-9]*$"  //负整数
"^-?\d+$"    //整数
"^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0)
"^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数
"^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0)
"^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数
"^(-?\d+)(\.\d+)?$"  //浮点数
"^[A-Za-z]+$"  //由26个英文字母组成的字符串
"^[A-Z]+$"  //由26个英文字母的大写组成的字符串
"^[a-z]+$"  //由26个英文字母的小写组成的字符串
"^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串
"^\w+$"  //由数字、26个英文字母或者下划线组成的字符串
"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址
"^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url
/^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/   // 年-月-日
/^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/   // 月/日/年
"^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$"   //Emil
"(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)?"   //电话号码
"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$"   //IP地址

2006年07月27日

No.1直接document.write

<script language="javascript">
document.write("<script src=’test.js’><\/script>");
</script>

No.1动态改变已有script的src属性

<script src=” id="s1"></script>
<script language="javascript">
s1.src="test.js"
</script>

No.1动态创建script元素
<script>
var s2 = document.createElement("script");
s2.src="test.js"
document.body.insertAdjacentElement("BeforeBegin",s2);
</script>

2006年04月11日

Web站点开发施分



明确自己需要信息分学(information taxonomy)是一回事,而知道如何用它是另一回事。采用以下的技巧将帮助你建立一个有用的Web站点。



学(Taxonomy)是描述信息组织后面指的技术术语——Web开发是一个需要注的重点问题一个Web开发当知道如何利用分学的基本原理来设计一个逻辑清晰、组织良好,且有效的Web站点构架。通理解信息分学相并将其用到Web站点的程中,Web开发可以将其成果的价和功能最大限度的行提升。



信息分学的两个关键方面是分类结构(taxonomy structure)和分类视图taxonomy view)。前者提供了在内容管理程中内容行分的方案。后者是描述呈Web上的信息、概念,以及必条件等内容型的概念模型。它表示了站点访问者可内容的逻辑,并且作Web站点设计入模查询引擎。些概念合起来可以Web站点开发最大化提供指。如果能正确的些概念,将会得到很好的



指向分施道路的三位一体指南


学的目的在于在组织unstructured的信息世界中建立构。分施道路充曲折。了能朝着目不断前,你必有一个指南。很多的文章、籍和演示材料出了分学具体的一些方法和技巧,但其中重要内容和根本主题总围绕着以下三信息构架中的关键因素:商业关系、用,以及内容(如A所示)。些因素反映了大多数分类项目中所需的基本商条件。从略角度而言,三因素成了指向分类实施道路的三位一体指南trinity compass。以下因素行描述:



业关系是指在业对行分类时的商业环境,如可能用到分学的Web用程序、企文化、去以及当前的分,以及组织内部和整个界的早期信息。



户则指分的目,比如用概况、用在信息使用模式上的各自特点等等。



内容是指将会通化或在其上建立分学的信息种类



指向分施道路的三位一体指南



类实



在三位一体指南的帮助下,我可以定义处理商业关系、内容以及用的分类实程,并遵循此践。B出了具有代表性的分类实程的步骤来看看对每的描述。



类实



团队组



团队组合是关键的一当得到足。成功的分类实施需要分专业以及文化和相内容的深入了解。然而,要找到一群同专业组织能力的专业人士并不现实的。来看,如果在同一团队中同了分学和问题专致效率低下,因二者都只注于目的不同方面,对对象区分级时造成冲突和混乱。尽管分实际结构很感趣,问题专们则会主要考内容覆盖范术语,和注一问题



此外,分Web站点开发的很多方面有关联,其中包括Web站点设计、内容管理,以及Web搜索引擎。因此,分类团队负责这些方面的Web开发团队合作。



理想的方法是通过专门的分类实团队taxonomy development team)和分利益集taxonomy interest group)在同其他Web开发组织合作中不同的技术进行描述,并在建分类团体的程中强调这些技需求。人员选择准根据目的化会有很多不同。通常考的条件是当熟悉整个目,具定位用能力,了解已有的组织,理解企文化。



类实团队应当包括来自技和商二者的成,例如包括信息家(information professionals)、管理librarians)、Web构架Web architects),以及信息构架information architects)。团队应类结构和分类视图实际实负责。在理想情况下,当由同精通信息管理和Web开发的信息构架领导整个目。指定的信息构架需要同分利益集以及其他的Web团队进行合作。



利益集团应当由问题专家或者来自商业团体且文化及相内容具深入了解的内容成。于小型目,集可能仅仅由一部分注分类过程的用户组成。



类组织实际结构需要根据组织的大小整。



类组织示例



类结构信息组织、信息找恢、信息映射



信息构架、信息家、料管理



问题专/内容家,内容管理



类视图 Web站点设计Web开发信息构架Web构架Web设计Web开发



问题专/内容家、内容用






一旦建了分类实团队,首要任务应当是定类项目的范。分类实团队以及分利益集团应当共同参与到定建工作中来。下面列出了问题的示例,按照三位一体指南的三要素来组织



业关



的目的是什



将如何用分学?



类设计的数据入来源是什?(可能包括国会图书馆、已有的目列表以及术语表等等)



内容



内容范是什?(可能包括整个公司和组织单元等)



将建立在哪些内容来源之上?(特是分以内的内容的定位)






会使用分?(可能包括雇、客,以及合作伙伴等等)



有什么样的描述?



步应度量分类值行定于一个增型的Web站点(enhanced Web sites),分的基准当按照同新建立站点的比来定。例如,按照每访问找特定信息所需要的鼠数定



建分



建分可以采用手、自,或者二者的合的方式。程将包括关关系、内容,以及定中用的分析。分析果将作包括分类结构和分类视图的分类设计入数据。分类实团队对类设计实际机制负责,而分利益集团则负责为内容包括范、命名,以及注等提供咨



按照可用源和目的时间安排,分类结构和分类视图视图设计可以按照先后序来行。所有通类视图表示的概念需要通类结行正确分可以保证每一内容都可以集中根据相同的分机制组织



在分类结构和分类视图之外,关标准和指。在分类视图和分类结构中的种类当符合某类规则而言之,必内容于所定的种类。内容管理人内容归类候就可以参考规则。如果使用了内容注自工具,规则可以被用来用程序。相关标准和指有助于确保分的一致性,并内容管理系和搜索引擎程的量提供了保



类实



下一包括了置分,以及行内容注。程常常在分学中称放置(populating似于分建,分施可以采用手、自,或者两者兼用的方式。步骤的目在于将分用到Web站点设计、搜索引擎,以及内容管理域。



Web站点设计,分类视图应用在站点构和界面的起步设计阶段。主要着眼于概念和分,而不是术语注,或形。在定内容细节层次方面,从一般到特殊的程可能需要多次反。分类视图种类包括了站点表、、内容安排,以及框架。最的站点划将通过对最后迭代(iteration)出的分类视图采用形化理的方式来实现



于搜索引擎,可以通不同的方式来施。分类结构将作机制添加到搜索引擎中,由此有助于行相关训练或者将其同搜索引擎集成以类别查看和找的集合体。



类实施的最大挑之一是在搜索引擎设计和分学研究之的同步问题,尤其于那些在索引程中没有采用分学内容注的搜索引擎。在这样的情况下,站点的访问者如果先后使用搜索和浏览相同条目两方法,却得到不同的果,给访问来很大的混乱。



类结构需要集成到内容管理程当中。内容分类应当位于内容管理工作流的第一段,就如同成本核(review and approval)一。如果没有内容管理工具,可以通动设置或从外部已建的分方法入的方式,将分类结构装到相工具。通内容管理程,内容可以根据分学手或自注。话说,内容很好的适了分



测试测试,再测试



测试的目是确中的错误和矛盾。测试结果可以用于随后的分类设计测试应当同整个Web用程序的用性测试过程相合,包括后台内容管理测试和前台站点访问测试。以下出了测试检查列表示例:



出特定信息主,站点访问者能否松找到主所包括或相的内容?



出特定信息主,站点访问者需要单击多少次鼠才能看到所需的信息?



出特定的任,站点访问者是否能在合适的时间里完成此任



注所表达出的信息是否清楚?



内容排列的级别是否符合站点访问者的需要?



内容组织结构是否能使内容管理者松的内容行分



测试结果需要记录下来,然后同基准统计数据行比,以有助于量方法的改



维护



类设计细节调整是同内容管理相似的需要一直行的程。随着组织结构的增和将其不断引入到分类实施中,商业关系、内容,和用将会不断生改。新的概念、术语以及信息需求将不断集成到分学当中。管理程的不断于保定性和流性提供了保障。



更好的分类结来更好的信息访问



学的程已不断增和改的信息组织框架。分学很大程度上Web站点设计、内容管理和搜索引擎等方面来了便利。如果能很好施,分将促Web内容构化,并由此改进对信息的访问




 


本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年04月10日

禁止back space键:

禁止ctrl+n:onkeydown=”if(event.keyCode==78 && event.ctrlKey) return false;”


当我们不想让用户后退到a页面

可以在a页面跳转后将a页面的window.location=b页面url,

这样后来用户想后退到a页面时,进入的就是b页面

使用java提供的方法,在jsp或者servlet中都可以
<%
response.setHeader(“Pragma”,”No-cache”);
response.setHeader(“Cache-Control”,”no-cache”);
response.setDateHeader(“Expires”,0);
%>
2,使用HTML标记,如下面:






HKEY_CURRENT_USERSoftware\Policies\Microsoft\Internet Explorer\Restrictions

适用范围:Windows NT/2000
通过修改注册表,可以禁止用户使用IE浏览器的“前进”/“后退”按钮。
步骤1:运行注册表编辑器,找到HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Restrictions子键。
步骤2:找到或新建“NoNavButtons”键值项,其数据类型是“字符串值”,设置其键值为“1”,表示禁用IE浏览器的“前进”/“后退”按钮;设置其值为“0”,则表示启用IE浏览器的“前进”/“后退”按钮。
注意
如果希望修改计算机所有用户的设置,其相应操作子键为: HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\lnternet Explorer\Restions。同样子键lnternet Explorer和Restrictions的键值项都必须新建。






灵感写回忆录(118978) 10:48:44
要跳转页面的时候,this.location.replace(“FooURL.html”);便可,这样连回退图标都没有
灵感写回忆录(118978) 10:49:07
喔,好像是location.href.replace,反正就是这样,好久没有写了

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月17日

一套值预验证控件,是解决常见bug的有效办法


今天看到了博客园的这篇文章:细节-质量-态度
摘一段如下:


来看看一个TextBox可能涉及到的测试项,下面所列出的测试项,在实际项目中数目还会有更多,
有几条也可以合为一个,但一般的项目都会涉及到:
1.      是否必输
2.      输入长度限制是否正确
3.      特殊输入类型的检查是否正确
l         数字 :位数正确吗?
l         Email:是否有效
l         货币:小数位,四舍五入正确吗?货币类型?
l         电话:格式化正确吗?
l         小数:小数位数正确吗?
l         名字:如果是老外的名字,首字母大写
4.      Tab键顺序正确吗?
5.      颜色表示正确吗?(有可能分为必输项,非必输项,当前输入项)
6.      文本框长度和数据库中长度对应吗?
7.      输入的长度不足时是否自动补位?
8.      初始化时焦点的设置正确吗?
9.      初始化时Enable属性设置正确吗?
10.  初始化时的内容正确吗?
11.  当界面上进行其他操作时,文本的Enable属性设置
12.  文本框命名
13.  如果有回车替换Tab,是否正确
14.  是否可以多行
15.  字体设置正确吗?
16.  取Text属性时对空格的控制(Trim)正确吗?

但是大家可以算算这样一个界面,只有5个TextBox,但是在TextBox处理上隐含了多少个bug,50个?太多了,取一半,25个。

现在把添,删,查,改加上,再算算,这样一个简单的单表维护界面上就隐含了多少个bug,保守点也30个!要达到50也不是没有可能的。
如果我们再加上一些其他的CheckBox,ComboBox,ListBox什么的,编辑查看附件,发送什么的附加功能,测试点会膨胀到什么程度?

这个问题在数据库操作的企业应用软件中特别普遍。我们的软件在开始阶段出现的也大多是这类问题。如果有一个问题没有测试出来而在用户那里出现了,这时程序员会推卸责任,测试人员觉得冤枉,总之这种低级错误让人不爽。


问题在哪呢?是在于对细节的态度吗?


关于细节的重性,我们已经非常重视了。但人总有疏忽的时候,不能指望一个人总是不犯错。


问题在于没有一个良好的机制,一个注重细节检查的机制。让自动化的、预先检查的机制,来代替成本非常之高的人工检查。


一个很好的、行之有效的解决办法,就是“验证控件”。把原来程序员要单独的、一个一个去检查的控件,封装成一套完整的、带验证方法的控件,把保贵的程序员的精力解放出来。


比如,我们可以做字符串控件,有个最长值的属性;可以做数值控件,只能录入数值,这样程序员取得的值直接是数值而不用再手工转换;数值控件也有很多种,整数的,小数的等等;email控件、phone控件、日期控件等等。


做控件的时间是可控的、很少的;而在有繁杂界面的企业应用中,一套这样的控件可以节省的测试人工成本、避免出错的带来的经济损失是非常有用的,收益是永久的。一套控件可以用在其它的案例中,收益更是长久的。


我看到过的一些web framework,无不把控件的值校验功能放在核心层面,这样做也已经证明是非常成功的。哪些?Ruby on Rails!TurboGears!Java下的一些大的筐架。


.Net下面为什么没有?等着你自己来做呢。微软可没有这个经验。看了原文后面的评论,感觉还是有很多还没有意识这个问题的根本。还在争论什么面向对象编程、面向过程编程,希望多“想些实际问题,少谈些主义”。能解决问题的方法,就是好方法。


再补充一点:不能把所有的事情都丢给测试 人员。测试人员的时间、精力也一样是有限的,测试本身也不是万能的。如果软件质量不好,统统怪测试人员,那样一方面解决不了根本问题,程序员该犯的错还是会继续犯;一方面还会在公司内部造成测试与开发的对立,测试永远低开发一等,这样不利于良好的团队合作精神的养成。


我是项目经理,我一向的观点是,不能把保证软件质量的担子全部落到最后测试的身上。软件质量的责任是整个小组中每一个人都应该承担的,每一个环节都应该重视的。

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月10日






数月来学习web标准,并遵循标准设计和制作web页面。一直想写点什么,整理一下自己的心得体会。写这篇文章,主要是针对中文排版设计,英文排版因为很少做,所以不涉及。





先介绍如何设定字体、颜色、大小、段落空白等比较简单的应用,后面再介绍下比如首字下沉、首行缩进。最后讲一些常用的web页面中文排版,比如中文字的截断、固定宽度词内折行(word-wrapword-break)等等。因为只是写一些应用方面的心得,如果需要完整的CSS属性介绍,请参考CSS手册。





1、如何设定文字字体、颜色、大小 —— 使用font





font-style设定斜体,比如font-style: italic;
font-weight
设定文字粗细,比如
font-weight: bold;
font-size
设定文字大小,比如font-size: 12px;(或者9pt,不同单位显示问题参考CSS手册)

line-height
设定行距,比如line-height: 150%;
color
设定文字颜色(注意不是font-color),比如
color: red;
font-family
设定字体,比如font-family : “Lucida Grande”, Verdana, Lucida, Arial, Helvetica, 宋体,sans-serif;(这是通用的写法)





以上都可以写在一行font属性里(除了color属性需要单独写):
font: italic bold 12px/150% “Lucida Grande”, Verdana, Lucida, Arial, Helvetica,
宋体,sans-serif;





2、如何控制段落排版 —— 使用margintext-align





中文段落使用

标签,左右(相当于缩进)、段前段后的空白,都可以用margin。比如:
p{
 margin: 18px 6px 6px 18px; /*
分别是上、右、下、左,十二点开始的顺时针方向*/
}
文字的对齐方式用text-align,比如:

p{
 text-align: center;  /*
居中对齐*/
}
对齐方式还有leftrightjustify(两端对齐)





PS.谈起margin,我习惯于在写CSS的时候为所有的标签定义margin: 0; 因为时而出现由于默认的margin值导致页面排版问题,而自己找不到原因(特别注意的是ul/ol/p/dt/dd等标签)





3、竖排文字 —— 使用writing-mode





writing-mode属性有两个值lr-tbtb-rl,前者是默认的左-右、上-下,后者是上-下、右-左。
比如:
p{
 writing-mode: tb-rl;
}
可以结合direction排版。





4、项目符号的问题 —— 使用list-style





CSS里项目符号有disc(实心圆点)、circle(空心圆圈)、square(实心方块)、decimal(阿拉伯数字)、lower-roman(小写罗马数字)、upper-roman(大写罗马数字)、lower-alpha(小写英文字母)、upper-alpha(大写英文字母)、none(无)。比如设定一个列表(ulol)的项目符号为方块,如:
li{
 list-style: square;
}
另外list-style还有一些值,比如可以采用一些小图片作为项目符号,在list-style下直接写url(“图片地址”)就可以了。注意如果一个项目列表的左外补丁(margin-left)设为零的时候,list-style-position: outside(默认是outside)的项目符号不会显示。可惜的是上述的项目符号似乎并不能设定大小,圆点和方块始终是那么点。并且不能设定垂直方向上的对齐。





5、首字下沉 —— 使用:first-letter





伪对象:first-letter配合font-sizefloat可以制作首字下沉效果。
比如:
p:first-letter{
 padding: 6px;
 font-size: 32pt;
 float: left;
}





6、首行缩进 —— 使用text-indent





text-indent可以使得容器内首行缩进一定单位。比如中文段落一般每段前空两个汉字。可以这么写:
p{
 text-indent: 2em; /*em
是相对单位,2em即现在一个字大小的两倍*/
}
如果font-size12px的话,那么text-indent: 2em则缩进24px





7、关于汉字注音 —— 使用ruby标签和ruby-align属性





比如说注音zhu yin,可以利用ruby-align设置对齐方式。这是在CSS手册里面看到的,具体可以自行查阅ruby-align项。





8、固定宽度汉字截断 —— 使用text-overflow





用后台语言可以对从数据库里的字段内容做截断处理,比如说截12个汉字(之后用省略号)。但是有时还需要html标签的过滤等,而用CSS来控制则没有这个问题。比如对列表应用以下样式:
li{
 overflow:hidden;
 text-overflow:ellipsis;
 white-space:nowrap;
}
不过只能处理文字在一行上的截断,不能处理多行。





9、固定宽度汉字(词)折行 —— 使用word-break





举个例子,比如说要在一个固定宽度容器里面显示很多地名(假设以空格分隔),为了避免地名中间断开(即一个字在上面而另一个字折断到下一行去了)。则可以使用word-break。比如:



南京上海 上海上 上海上海 南京 上海上海上海 南京上海 上海 南京上海 上海 南京 上海 南京 上海 南京 上海 南京 上海 南京 上海 南京上海 上海 南京上海 上海

值得注意的是里面的空格不能以 代替(最少要有一个软空格)。

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2006年02月05日

以keso模版为基础,在公告中要添加以下代码:






#main {
   WIDTH: 95%;MARGIN-RIGHT: 20em
}
HTML {
 PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px
}
BODY {
 PADDING-RIGHT: 2em; PADDING-LEFT: 2em; FONT-SIZE: 10pt; PADDING-BOTTOM: 0px; MARGIN: auto; COLOR: #555; PADDING-TOP: 0px; FONT-FAMILY: Verdana,Arial,sans-serif
}
A {
 COLOR: #aaa; TEXT-DECORATION: none
}
IMG {
 BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none
}
BR {
 LINE-HEIGHT: 0
}
BLOCKQUOTE {
 PADDING-LEFT: 2em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_blockquote.gif) #fafafa no-repeat left top
}
CODE {
 FONT-SIZE: 0.9em; LINE-HEIGHT: 1.5em; FONT-FAMILY: “Courier New”,Verdana,Arial,sans-serif
}
SAMP {
 FONT-SIZE: 0.9em; LINE-HEIGHT: 1.5em; FONT-FAMILY: “Courier New”,Verdana,Arial,sans-serif
}
TT {
 FONT-SIZE: 0.9em; LINE-HEIGHT: 1.5em; FONT-FAMILY: “Courier New”,Verdana,Arial,sans-serif
}
ACRONYM {
 CURSOR: help; BORDER-BOTTOM: #ccc thin dashed
}
abbr {
 CURSOR: help; BORDER-BOTTOM: #ccc thin dashed
}
#header {
 MARGIN-TOP: 1em; FONT-SIZE: 1.8em
}


#main H2 {
 FONT-SIZE: 1.2em; COLOR: #aaa
}
#comments {
 FONT-WEIGHT: bold; FONT-SIZE: 1em; COLOR: #aaa
}
#comments .post {
 BACKGROUND-COLOR: #f7f6f5
}
#comments .postTitle {
 PADDING-RIGHT: 2em; PADDING-LEFT: 2em; FONT-SIZE: 1.1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_comment.gif) no-repeat 5px 50%; PADDING-BOTTOM: 1em; PADDING-TOP: 1em
}
#comments .postText {
 FONT-WEIGHT: normal; PADDING-BOTTOM: 1em
}
#commentForm H3 {
 MARGIN-TOP: 2em; FONT-WEIGHT: bold; FONT-SIZE: 1.1em; COLOR: #aaa
}
#commentForm TABLE {
 BORDER-RIGHT: #ccc 3pt dashed; PADDING-RIGHT: 2.5em; BORDER-TOP: #ccc 3pt dashed; PADDING-LEFT: 2em; PADDING-BOTTOM: 1em; BORDER-LEFT: #ccc 3pt dashed; PADDING-TOP: 1em; BORDER-BOTTOM: #ccc 3pt dashed
}
#commentForm TD {
 FONT-SIZE: 0.9em; COLOR: #555
}
#commentForm INPUT {
 FONT-SIZE: 1em; COLOR: #555; FONT-FAMILY: Verdana,Arial,sans-serif
}
#commentForm TEXTAREA {
 FONT-SIZE: 1em; COLOR: #555; FONT-FAMILY: Verdana,Arial,sans-serif
}
#commentForm INPUT {
 BORDER-RIGHT: medium none; PADDING-RIGHT: 0.3em; BORDER-TOP: medium none; PADDING-LEFT: 0.3em; PADDING-BOTTOM: 0px; BORDER-LEFT: medium none; PADDING-TOP: 0px; BORDER-BOTTOM: #ccc thin dashed
}
#commentForm INPUT:unknown {
 BORDER-BOTTOM: #888 thin dashed
}
#commentForm TEXTAREA {
 BORDER-RIGHT: #ccc thin dashed; PADDING-RIGHT: 0.3em; BORDER-TOP: #ccc thin dashed; PADDING-LEFT: 0.3em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_mail.gif) no-repeat right bottom; PADDING-BOTTOM: 0.3em; BORDER-LEFT: #ccc thin dashed; PADDING-TOP: 0.3em; BORDER-BOTTOM: #ccc thin dashed
}
#commentForm TEXTAREA:unknown {
 BORDER-RIGHT: #888 thin dashed; BORDER-TOP: #888 thin dashed; BORDER-LEFT: #888 thin dashed; BORDER-BOTTOM: #888 thin dashed
}
#rightmenu {
  WIDTH: 20%;PADDING-RIGHT: 0.5em; PADDING-LEFT: 0.5em; RIGHT: 2em; PADDING-BOTTOM: 0.5em; MARGIN: -2.2em 0px; WIDTH: 18em; COLOR: #aaa; PADDING-TOP: 0.5em; POSITION: absolute; TOP: 0px
}
#rightmenu H3 {
 MARGIN-TOP: 0.5em; PADDING-LEFT: 1.7em; FONT-SIZE: 1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_h3.gif) no-repeat 0% 50%
}
#rightmenu UL {
 MARGIN-TOP: -0.5em; LIST-STYLE-TYPE: none
}
#rightmenu UL LI {
 PADDING-LEFT: 0.7em; MARGIN: 0.3em 0px 0.3em -1.6em
}
#rightmenu UL LI:hover {
 BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_array.gif) no-repeat left center
}
#rightmenu UL LI A {
 BORDER-BOTTOM: #ccc thin dashed
}
#rightmenu UL LI A:hover {
 BORDER-BOTTOM: #888 thin dashed
}
.dateTitle {
 BORDER-RIGHT: #ccc 3pt dashed; PADDING-RIGHT: 2em; BORDER-TOP: #ccc 3pt dashed; MARGIN-TOP: 1.5em; PADDING-LEFT: 2em; FONT-WEIGHT: bold; FONT-SIZE: 1.1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_dateTitle.gif) #f7f6f5 no-repeat 5px 50%; PADDING-BOTTOM: 0.3em; BORDER-LEFT: #ccc 3pt dashed; COLOR: #aaa; PADDING-TOP: 0.3em; BORDER-BOTTOM: medium none
}
.post {
 BORDER-RIGHT: #ccc 3pt dashed; BORDER-TOP: #ccc 3pt dashed; MARGIN-BOTTOM: 1em; BORDER-LEFT: #ccc 3pt dashed; BORDER-BOTTOM: #ccc 3pt dashed
}
.post A {
 BORDER-BOTTOM: #ccc thin dashed
}
.post A:hover {
 BORDER-BOTTOM: #888 thin dashed
}
.post BR {
 LINE-HEIGHT: 1em
}
UNKNOWN {
 PADDING-LEFT: 2.3em; FONT-SIZE: 1em
}
.post TABLE {
 MARGIN: 2em; TEXT-ALIGN: center
}
.post H2 {
 MARGIN: 0px
}
.post H5 {
 MARGIN: 0px
}
UNKNOWN {
 MARGIN: 1em 0px 0px 2em
}
#Navigator {
 MARGIN: 0.3em; TEXT-ALIGN: center
}
#Description {
 MARGIN: 0.3em; TEXT-ALIGN: center
}
.post H2 {
 PADDING-RIGHT: 2em; PADDING-LEFT: 2em; FONT-WEIGHT: bold; FONT-SIZE: 1.1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_postTitle.gif) no-repeat 5px 100%; PADDING-BOTTOM: 0px; COLOR: #aaa; PADDING-TOP: 0.5em
}
.post H5 {
 PADDING-RIGHT: 2em; PADDING-LEFT: 2em; FONT-WEIGHT: bold; FONT-SIZE: 1.1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_postTitle.gif) no-repeat 5px 100%; PADDING-BOTTOM: 0px; COLOR: #aaa; PADDING-TOP: 0.5em
}
.postTitle {
 PADDING-RIGHT: 2em; PADDING-LEFT: 2em; FONT-WEIGHT: bold; FONT-SIZE: 1.1em; BACKGROUND: url(http://bolgimg.b0.upaiyun.com/images/blog_donews_com/wangkewoft/42340/o_postTitle.gif) no-repeat 5px 100%; PADDING-BOTTOM: 0px; COLOR: #aaa; PADDING-TOP: 0.5em
}
.postText {
 PADDING-RIGHT: 2.2em; PADDING-LEFT: 2.2em; PADDING-BOTTOM: 0px; PADDING-TOP: 0px
}
.postText {
 COLOR: #555
}
.postText A {
 COLOR: #555
}
.postFoot {
 BORDER-RIGHT: #ccc 3pt dashed; PADDING-RIGHT: 0px; BORDER-TOP: #ccc 3pt dashed; PADDING-LEFT: 0px; FONT-SIZE: 0.9em; PADDING-BOTTOM: 0.3em; MARGIN: 1em 10em 0px; BORDER-LEFT: #ccc 3pt dashed; PADDING-TOP: 0.1em; BORDER-BOTTOM: medium none; BACKGROUND-COLOR: #f7f6f5; TEXT-ALIGN: center
}
.postFoot {
 COLOR: #999
}
.postFoot A {
 COLOR: #999
}
#tagline {
 DISPLAY: none
}
#nadframe {
 DISPLAY: none
}
#classnavbar {
 DISPLAY: none
}
#MyLinks1_XMLLink {
 DISPLAY: none
}
#MyLinks1_Syndication {
 DISPLAY: none
}
#MyLinks1_HomeLink {
 DISPLAY: none
}

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年12月05日

































本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年11月17日

AJAX开发简略



 







文档说明




 



参与人员:




 

















作者



网名



联络



柯自聪



eamoi   educhina



eamoi@163.com(技术) zcke0728@hotmail.com(版权)




 




 




 




 



发布记录:




 




















版本



日期



作者



说明



1.0



2005-10-28



柯自聪



创建,第一版




 




 




 




 




 



链接:




 














类别



网址



Blog



http://www.blogjava.net/eamoi/



MSN-Space



http://spaces.msn.com/members/eamoi/




 




 



OpenDoc版权说明:



本文档版权归原作者所有。



在免费、且无任何附加条件的前提下,可在网络媒体中自由传播。



如需部分或者全文引用,请事先征求作者意见。



如果本文对您有些许帮助,表达谢意的最好方式,是将您发现的问题和文档改进意见及时反馈给作者。当然,倘若有时间和能力,能为技术群体无偿贡献自己的所学为最好的回馈。




 





AJAX开发简略1



一、AJAX定义3



二、现状与需要解决的问题3



三、为什么使用AJAX. 4



四、谁在使用AJAX. 6



五、用AJAX改进你的设计6



例子1:数据校验7



例子2:按需取数据—级联菜单7



例子3:读取外部数据7



六、AJAX的缺陷7



七、AJAX开发8



7.1、AJAX应用到的技术8



A、XMLHttpRequest对象8



B、Javascript. 9



C、DOM. 9



D、XML. 9



7.2、AJAX开发框架9



A、初始化对象并发出XMLHttpRequest请求9



B、指定响应处理函数10



C、发出HTTP请求10



D、处理服务器返回的信息11



E、一个初步的开发框架11



7.3、简单的示例13



A、数据校验13



B、级联菜单14



参考文章:16



在使用浏览器浏览网页的时候,当页面刷新很慢的时候,你的浏览器在干什么?你的屏幕内容是什么?是的,你的浏览器在等待刷新,而你的屏幕内容是一片空白,而你在屏幕前苦苦的等待浏览器的响应。开发人员为了克服这种尴尬的局面,不得不在每一个可能需要长时间等待响应的页面上增加一个DIV,告诉用户“系统正在处理您的请求,请稍候……”。


现在,有一种越来越流行越热的“老”技术,可以彻底改变这种窘迫的局面。那就是AJAX。如今,随着GmailGoogle-maps的应用和各种浏览器的支持,AJAX正逐渐吸引全世界的眼球。


一、AJAX定义


AJAXAsynchronous JavaScript and XML)其实是多种技术的综合,包括JavascriptXHTMLCSSDOMXMLXSTLXMLHttpRequest。其中:


使用XHTMLCSS标准化呈现,使用DOM实现动态显示和交互,使用XMLXSTL进行数据交换与处理,使用XMLHttpRequest对象进行异步数据读取,使用Javascript绑定和处理所有数据。


AJAX提出之前,业界对于上述技术都只是单独的使用,没有综合使用,也是由于之前的技术需求所决定的。随着应用的广泛,AJAX也成为香饽饽了。


二、现状与需要解决的问题


传统的Web应用采用同步交互过程,这种情况下,用户首先向HTTP服务器触发一个行为或请求的呼求。反过来,服务器执行某些任务,再向发出请求的用户返回一个HTML页面。这是一种不连贯的用户体验,服务器在处理请求的时候,用户多数时间处于等待的状态,屏幕内容也是一片空白。如下图:
传统web响应过程1.jpg传统web响应过程2.jpg


自从采用超文本作为Web传输和呈现之后,我们都是采用这么一套传输方式。当负载比较小的时候,这并不会体现出有什么不妥。可是当负载比较大,响应时间要很长,1分钟、2分钟……数分钟的时候,这种等待就不可忍受了。严重的,超过响应时间,服务器干脆告诉你页面不可用。另外,某些时候,我只是想改变页面一小部分的数据,那为什么我必须重新加载整个页面呢?!当软件设计越来越讲究人性化的时候,这么糟糕的用户体验简直与这种原则背道而驰。为什么老是要让用户等待服务器取数据呢?至少,我们应该减少用户等待的时间。现在,除了程序设计、编码优化和服务器调优之外,还可以采用AJAX


三、为什么使用AJAX


与传统的Web应用不同,AJAX采用异步交互过程。AJAX在用户与服务器之间引入一个中间媒介,从而消除了网络交互过程中的处理—等待—处理—等待缺点。用户的浏览器在执行任务时即装载了AJAX引擎。AJAX引擎用JavaScript语言编写,通常藏在一个隐藏的框架中。它负责编译用户界面及与服务器之间的交互。AJAX引擎允许用户与应用软件之间的交互过程异步进行,独立于用户与网络服务器间的交流。现在,可以用Javascript调用AJAX引擎来代替产生一个HTTP的用户动作,内存中的数据编辑、页面导航、数据校验这些不需要重新载入整个页面的需求可以交给AJAX来执行。
AJAX web响应过程1.jpgAJAX web响应过程2.jpg


使用AJAX,可以为ISP、开发人员、终端用户带来可见的便捷:


l         减轻服务器的负担。AJAX的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。


l         无刷新更新页面,减少用户心理和实际的等待时间。特别的,当要读取大量的数据的时候,不用像Reload那样出现白屏的情况,AJAX使用XMLHTTP对象发送请求并得到服务器响应,在不重新载入整个页面的情况下用Javascript操作DOM最终更新页面。所以在读取数据的过程中,用户所面对的不是白屏,是原来的页面内容(也可以加一个Loading的提示框让用户知道处于读取数据过程),只有当数据接收完毕之后才更新相应部分的内容。这种更新是瞬间的,用户几乎感觉不到。


l         带来更好的用户体验。


l         可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。


l         可以调用外部数据。


l         基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。


l         进一步促进页面呈现和数据的分离。


四、谁在使用AJAX


在应用AJAX开发上面,Google当仁不让是表率。OrkutGmailGoogle GroupsGoogle MapsGoogle Suggest都应用了这项技术。AmazonA9.com搜索引擎也采用了类似的技术。


微软也在积极开发更为完善的AJAX应用:它即将推出代号为AtlasAJAX工具。Atlas的功能超越了AJAX本身,包括整合Visual Studio的调试功能。另外,新的ASP.NET控件将使客户端控件与服务器端代码的捆绑更为简便。Atlas客户脚本框架(Atlas Clent Script Framework)也使与网页及相关项目的交互更为便利。但Visual Studio 2005中并不包含此项功能。


微软最近宣布Atlas客户脚本框架将包含如下内容(详细资料请访问Atlas计划网站):


* 一个可扩展的核心框架,它添加了JavaScript功能:如生命同时期管理、继承管理、多点传送处理器和界面管理。


* 一个常见功能的基本类库,有丰富的字符串处理、计时器和运行任务。


* HTML附加动态行为的用户界面框架。


* 一组用来简化服务器连通和网络访问的网络堆栈。


* 一组丰富的用户界面开发控件,如:自动完成的文本框、动画和拖放。


* 处理浏览器脚本行为差异的浏览器兼容层面。


典型的,微软将AJAX技术应用在MSN Space上面。很多人一直都对MS Space服务感到很奇怪,当提交回复评论以后,浏览器会暂时停顿一下,然后在无刷新的情况下把我提交的评论显示出来。这个就是应用了AJAX的效果。试想,如果添加一个评论就要重新刷新整个页面,那可真费事。


目前,AJAX应用最普遍的领域是GIS-Map方面。GIS的区域搜索强调快速响应,AJAX的特点正好符合这种需求。


五、用AJAX改进你的设计


AJAX虽然可以实现无刷新更新页面内容,但是也不是什么地方都可以用,主要应用在交互较多、频繁读数据、数据分类良好的Web应用中。现在,让我们举两个例子,看看如何用AJAX改进你的设计。


例子1:数据校验


在输入form表单内容的时候,我们通常需要确保数据的唯一性。因此,常常在页面上提供“唯一性校验”按钮,让用户点击,打开一个校验小窗口;或者等form提交到服务器端,由服务器判断后在返回相应的校验信息。前者,window.open操作本来就是比较耗费资源的,通常由window. showModalDialog代替,即使这样也要弹出一个对话框;后者,需要把整个页面提交到服务器并由服务器判断校验,这个过程不仅时间长而且加重了服务器负担。而使用AJAX,这个校验请求可以由XMLHttpRequest对象发出,整个过程不需要弹出新窗口,也不需要将整个页面提交到服务器,快速又不加重服务器负担。


例子2:按需取数据级联菜单


以前,为了避免每次对菜单的操作引起的重载页面,不采用每次调用后台的方式,而是一次性将级联菜单的所有数据全部读取出来并写入数组,然后根据用户的操作用JavaScript来控制它的子集项目的呈现,这样虽然解决了操作响应速度、不重载页面以及避免向服务器频繁发送请求的问题,但是如果用户不对菜单进行操作或只对菜单中的一部分进行操作的话,那读取的数据中的一部分就会成为冗余数据而浪费用户的资源,特别是在菜单结构复杂、数据量大的情况下(比如菜单有很多级、每一级菜又有上百个项目),这种弊端就更为突出。


现在应用AJAX,在初始化页面时我们只读出它的第一级的所有数据并显示,在用户操作一级菜单其中一项时,会通过Ajax向后台请求当前一级项目所属的二级子菜单的所有数据,如果再继续请求已经呈现的二级菜单中的一项时,再向后面请求所操作二级菜单项对应的所有三级菜单的所有数据,以此类推……这样,用什么就取什么、用多少就取多少,就不会有数据的冗余和浪费,减少了数据下载总量,而且更新页面时不用重载全部内容,只更新需要更新的那部分即可,相对于后台处理并重载的方式缩短了用户等待时间,也把对资源的浪费降到最低。


例子3:读取外部数据


AJAX可以调用外部数据,因此,可以对一些开发的数据比如XML文档、RSS文档进行二次加工,实现数据整合或者开发应用程序。


六、AJAX的缺陷


AJAX不是完美的技术。使用AJAX,它的一些缺陷不得不权衡一下:


l         AJAX大量使用了JavascriptAJAX引擎,而这个取决于浏览器的支持。IE5.0及以上、Mozilla1.0NetScape7及以上版本才支持,Mozilla虽然也支持AJAX,但是提供XMLHttpRequest的方式不一样。所以,使用AJAX的程序必须测试针对各个浏览器的兼容性。


l         AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的;有的用户还经常搞不清楚现在的数据是旧的还是已经更新过的。这个就需要在明显位置提醒用户“数据已更新”。


l         对流媒体的支持没有FLASHJava Applet好。


l         一些手持设备(如手机、PDA等)现在还不能很好的支持Ajax


七、AJAX开发


到这里,已经可以清楚的知道AJAX是什么,AJAX能做什么,AJAX什么地方不好。如果你觉得AJAX真的能给你的开发工作带来改进的话,那么继续看看怎么使用AJAX吧。


7.1AJAX应用到的技术


AJAX涉及到的7项技术中,个人认为JavascriptXMLHttpRequestDOMXML比较有用。


AXMLHttpRequest对象


XMLHttpRequestXMLHTTP组件的对象,通过这个对象,AJAX可以像桌面应用程序一样只同服务器进行数据层面的交换,而不用每次都刷新界面,也不用每次将数据处理的工作都交给服务器来做;这样既减轻了服务器负担又加快了响应速度、缩短了用户等待的时间。


IE5.0开始,开发人员可以在Web页面内部使用XMLHTTP ActiveX组件扩展自身的功能,不用从当前的Web页面导航就可以直接传输数据到服务器或者从服务器接收数据。,Mozilla1.0以及NetScape7则是创建继承XML的代理类XMLHttpRequest;对于大多数情况,XMLHttpRequest对象和XMLHTTP组件很相似,方法和属性类似,只是部分属性不同。


XMLHttpRequest对象初始化:





XMLHttpRequest对象的方法:


























方法


描述


abort()


停止当前请求


getAllResponseHeaders()


作为字符串返回完整的headers


getResponseHeader(“headerLabel”)


作为字符串返回单个的header标签


open(“method”,”URL”[,asyncFlag[,"userName"[, "password"]]])


设置未决的请求的目标 URL,方法,和其他参数


send(content)


发送请求


setRequestHeader(“label”, “value”)


设置header并和请求一起发送


XMLHttpRequest对象的属性:


























属性


描述


onreadystatechange


状态改变的事件触发器


readyState


对象状态(integer):


0 = 未初始化


1 = 读取中


2 = 已读取


3 = 交互中


4 = 完成


responseText


服务器进程返回数据的文本版本


responseXML


服务器进程返回数据的兼容DOMXML文档对象


status


服务器返回的状态码, 如:404 = “文件未找到200 =”成功


statusText


服务器返回的状态文本信息


BJavascript


Javascript一直被定位为客户端的脚本语言,应用最多的地方是表单数据的校验。现在,可以通过Javascript操作XMLHttpRequest,来跟数据库打交道。


CDOM


DOMDocument Object Model)是提供给HTMLXML使用的一组API,提供了文件的表述结构,并可以利用它改变其中的内容和可见物。脚本语言通过DOM才可以跟页面进行交互。Web开发人员可操作及建立文件的属性、方法以及事件都以对象来展现。比如,document就代表页面对象本身。


DXML


通过XMLExtensible Markup Language),可以规范的定义结构化数据,是网上传输的数据和文档符合统一的标准。用XML表述的数据和文档,可以很容易的让所有程序共享。


7.2AJAX开发框架


这里,我们通过一步步的解析,来形成一个发送和接收XMLHttpRequest请求的程序框架。AJAX实质上也是遵循Request/Server模式,所以这个框架基本的流程也是:对象初始化à发送请求à服务器接收à服务器返回à客户端接收à修改客户端页面内容。只不过这个过程是异步的。


A、初始化对象并发出XMLHttpRequest请求


为了让Javascript可以向服务器发送HTTP请求,必须使用XMLHttpRequest对象。使用之前,要先将XMLHttpRequest对象实例化。之前说过,各个浏览器对这个实例化过程实现不同。IEActiveX控件的形式提供,而Mozilla等浏览器则直接以XMLHttpRequest类的形式提供。为了让编写的程序能够跨浏览器运行,要这样写:


if (window.XMLHttpRequest) { // Mozilla, Safari, …


    http_request = new XMLHttpRequest();


} else if (window.ActiveXObject) { // IE


    http_request = new ActiveXObject(“Microsoft.XMLHTTP”);


}


有些版本的Mozilla浏览器处理服务器返回的未包含XML mime-type头部信息的内容时会出错。因此,要确保返回的内容包含text/xml信息。


http_request = new XMLHttpRequest();


http_request.overrideMimeType(‘text/xml’);


B、指定响应处理函数


接下来要指定当服务器返回信息时客户端的处理方式。只要将相应的处理函数名称赋给XMLHttpRequest对象的onreadystatechange属性就可以了。比如:


http_request.onreadystatechange = processRequest;


需要指出的时,这个函数名称不加括号,不指定参数。也可以用Javascript即时定义函数的方式定义响应函数。比如:


http_request.onreadystatechange = function() {


};


C、发出HTTP请求


指定响应处理函数之后,就可以向服务器发出HTTP请求了。这一步调用XMLHttpRequest对象的opensend方法。


http_request.open(‘GET’, ‘http://www.example.org/some.file’, true);


http_request.send(null);


open的第一个参数是HTTP请求的方法,为GetPost或者Head


第二个参数是目标URL。基于安全考虑,这个URL只能是同网域的,否则会提示“没有权限”的错误。这个URL可以是任何的URL,包括需要服务器解释执行的页面,不仅仅是静态页面。


第三个参数只是指定在等待服务器返回信息的时间内是否继续执行下面的代码。如果为True,则不会继续执行,直到服务器返回信息。默认为True


按照顺序,open调用完毕之后要调用send方法。send的参数如果是以Post方式发出的话,可以是任何想传给服务器的内容。不过,跟form一样,如果要传文件给服务器,必须先调用setRequestHeader方法,修改MIME类别。如下:


http_request.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”);


D、处理服务器返回的信息


在第二步我们已经指定了响应处理函数,这一步,来看看这个响应处理函数都应该做什么。


首先,它要检查XMLHttpRequest对象的readyState值,判断请求目前的状态。参照前文的属性表可以知道,readyState值为4的时候,代表服务器已经传回所有的信息,可以开始处理信息并更新页面内容了。如下:


if (http_request.readyState == 4) {


    // 信息已经返回,可以开始处理


} else {


    // 信息还没有返回,等待


}


服务器返回信息后,还需要判断返回的HTTP状态码,确定返回的页面没有错误。所有的状态码都可以在W3C的官方网站上查到。其中,200代表页面正常。


if (http_request.status == 200) {


    // 页面正常,可以开始处理信息


} else {


    // 页面有问题


}


XMLHttpRequest对成功返回的信息有两种处理方式:


responseText:将传回的信息当字符串使用;


responseXML:将传回的信息当XML文档使用,可以用DOM处理。


E、一个初步的开发框架


总结上面的步骤,我们整理出一个初步的可用的开发框架,供以后调用;这里,将服务器返回的信息用window.alert以字符串的形式显示出来:





7.3、简单的示例


接下来,我们利用上面的开发框架来做两个简单的应用。


A、数据校验


在用户注册的表单中,经常碰到要检验待注册的用户名是否唯一。传统的做法是采用window.open的弹出窗口,或者window. showModalDialog的对话框。不过,这两个都需要打开窗口。采用AJAX后,采用异步方式直接将参数提交到服务器,用window.alert将服务器返回的校验信息显示出来。代码如下:


之间增加一段form表单代码:
form-code.jpg
在开发框架的基础上再增加一个调用函数:


function userCheck() {


       var f = document.form1;


       var username = f.username.value;


       if(username==”") {


              window.alert(“用户名不能为空。“);


              f.username.focus();


              return false;


       }


       else {


              send_request(’sample1_2.jsp?username=’+username);


       }


}


看看sample1_2.jsp做了什么:


<%@ page contentType="text/html; charset=gb2312" errorPage="" %>


<%

String username = request.getParameter(“username”);

if(“educhina”.equals(username)) out.print(“用户名已经被注册,请更换一个用户名。“);

else out.print(“用户名尚未被使用,您可以继续。“);

%>


运行一下,嗯,没有弹出窗口,没有页面刷新,跟预想的效果一样。如果需要的话,可以在sample1_2.jsp中实现更复杂的功能。最后,只要将反馈信息打印出来就可以了。


示例1_1.jpg示例1_2.jpg


B、级联菜单


我们在第五部分提到利用AJAX改进级联菜单的设计。接下来,我们就演示一下如何“按需取数据”。


首先,在中间增加如下HTML代码:





   




       


   



   



       


   


   



       


   


   



       


   




                     经理室


             

 


                     开发部


             

 


在框架的基础上增加一个响应函数showRoles(obj)


//显示部门下的岗位


function showRoles(obj) {


       document.getElementById(obj).parentNode.style.display = “”;


       document.getElementById(obj).innerHTML = “正在读取数据…”


       currentPos = obj;


       send_request(“sample2_2.jsp?playPos=”+obj);


}


修改框架的processRequest函数:


// 处理返回信息的函数


function processRequest() {


  if (http_request.readyState == 4) { // 判断对象状态


    if (http_request.status == 200) { // 信息已经成功返回,开始处理信息


       document.getElementById(currentPos).innerHTML = http_request.responseText;


    } else { //页面不正常


      alert(“您所请求的页面有异常。“);


    }


  }


}


最后就是smaple2_2.jsp了:


<%@ page contentType="text/html; charset=gb2312" errorPage="" %>


<%

String playPos = request.getParameter(“playPos”);

if(“pos_1″.equals(playPos))

out.print(“  总经理
  
副总经理“);

else if(“pos_2″.equals(playPos))

out.println(“  总工程师
  
软件工程师“);

%>
运行一下看看效果:
示例2_1.jpg示例2_2.jpg


参考文章:





























作者:


fanscial


标题:


AJAX简介》


网址:


http://www.blogjava.net/fanscial/archive/2005/08/31/11628.html


作者:


Amour GUO


标题:


AJAX内部交流文档》


网址:


http://www.dragonson.com/doc/ajax.html


作者:


MoztwWiki


标题:


AJAX上手篇》


网址:


http://wiki.moztw.org/index.php/AJAX_%E4%B8%8A%E6%89%8B%E7%AF%87



 



本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”

2005年10月25日

用AJAX跟踪Google Adsense广告点击



功能



  1. 可以完整详细地获得每一个用户点击广告的数据。包括点击时间用户的IP页面来源地址被点击的广告网站地址,如果你的站点上保存了用户cookie的话,甚至可以查询到是哪位用户点了你的广告
  2. 用纯客户端javascript代码和AJAX技术实现点击监听和向服务端发送点击数据,服务端我用的是ASP脚本,只是用来保存点击数据和提供浏览器端的点击查询,可以更换为其他服务端脚本,如PHP,JSP等
  3. 数据保存方式为了简单,我用纯text文本保存,一行保存一条数据,数据字段用逗号分隔,这样方便用户将这个文本另存为csv格式,csv就能用excel打开了。
  4. 查看广告点击数据可设访问密码

安装和使用



  1. 下载这个文件解压出里面的adLog.asp文件
  2. 用记事本打开adLog.asp找到如下几行:

    Const TextFile = “adLog.txt” ‘保存点击数据的text文件,是相对路径,可以修改
    Const AccessPassword = “adLog” ‘查看点击时的访问密码,可以自行设定,如果无需身份认证,请将AccessPassword值改为”"即可
    Const SessionName = “google_ad_logger” ‘Session名称,用来保存访问密码到指定Session中
    Const WebCharset = “utf-8″ ‘网站的编码类型,如果是GB-2312,请自行修改
    Const UserName = “username” ‘用户名cookie,如果你的站没有用户cookie,就不用管了
    可以根据自己实际需要修改其值
  3. 修改完毕后将文件上传到你的web站点上,任何路径下都可以。这里注意:如果你的编码是gb-2312,请将文件用记事本打开,并选择另存为,将编码改回为ANSI。
  4. 修改你投放了google广告的页面文件,将以下代码插入你的页面任意位置:


    将其中的页面路径修改为你自己实际的地址
  5. 安装完毕以后页面就自动开始跟踪广告点击了
  6. 查看点击数据你可以上ftp直接下载你指定的文本文件查看,或者访问http://www.example.com/adlog.asp

技术原理


其实这也不是什么高深技术,原理及其简单,主要核心功能都是在客户端javascript中。



  • 通过查看发现google的广告代码全部放在一个iframe中。所以首先通过document.getElementsByTagName(“iframe”)得到页面中所有iframe标签的元素集保存到一个数组中
  • 然后遍历数组检查iframe.src值是否包含有”googlesyndication.com”这串字符串,如果有就认为这个iframe是google的广告显示iframe
  • 得到google显示广告的iframe后给这个iframe增加一个onfocus事件,这个事件就是当元素获得焦点时触发的事件
  • 在onfocus事件中检查window.status的值,也就是状态栏显示的字符串,如果匹配”go to”和”键连至”这几个字符串就提取中网址地址,这个地址就认为是被点击的广告网址
  • 利用AJAX立即将用户的点击数据POST到服务端纪录下来,这里的AJAX无需再响应服务端传回的数据了,只管发送出去即可

 


几个核心代码



  • 编写过windows程序的朋友一定知道微软的Visual Stdio中包含有一个Spy的小工具,这个小工具中就有一个功能用来监听某个窗口句柄的所有触发事件,用起来很爽,我在写这个广告纪录器时也自己实现了一个网页上用的Spy,代码如下:





    我就是用这种方法查看iframe上触发的事件,查看后发现鼠标单击iframe时能接收到的事件中有onbeforeactivate、onactivate、onfocusin、onfocus这四个,我就挑了onfocus来监听用户点击的
  • ajax部分我用的是XHConn组件,小巧灵活简单,很好使。
  • 前面讲解安装时我特意说过包含js的代码可以放在网页的任意位置,这里我用的是一个称作domFunction的js组件,这个组件可以实现循环查询DOM对象,直到发现DOM装载入页面并有效后再执行代码,相当于document.onload事件的作用,google adsense的广告有时候会显示很慢,用了这个Dom检查程序就可以保证每次页面装载都能查找到google的iframe,万无一失,也方便了用户添加代码时无需考虑位置的影响了。
  • 按理,这个程序应该写成一个asp外加一个js两个文件,但是看了Andy兄介绍的单页面应用程序(Single Page Application这篇文章,很是欣赏,所以特意将两个文件合写到一个文件中了
  • 服务端保存和读取文本文件的内容时,我用的分别是FSO和ADODB.Stream,如果你的站点不支持这些组件,请和我联系,我改写其他方式

遗憾



  • 最遗憾的是这个程序只能用在IE下启作用,Firefox下无法跟踪用户点击操作,原因是Firefox中ifrmae根本触发不了任何用户操作事件,去Mozilla上查看资料,官方说明了用document.getElementById(“iframe”).contentWindow这个对象,但是我尝试后还是毫无作用,只好作罢,等待高人解决。
  • 最惭愧的是我怎么也找不到在onfocus事件中判断用户鼠标左右键的方法,在iframe上点击鼠标右键也会触发事件的,程序会被认为一次有效的用户点击,这个问题一定要改改的。

Demo和下载


如果想立即查看下程序实际运行,我特意提供了一个demo文件:http://www.duduwolf.com/test/adLogDemo.asp,这个文件没有设访问密码,任何人都能查看点击数据,你也可以通过装载

这串代码立即从你的网站上实现点击跟踪,只不过点击后的数据是保存在我的网站上并且是公开的。
下载源文件:Google Adsense Click Logger
在线查看源代码:查看源代码(utf-8,如果显示乱码请修改当前页面编码)



这个程序我自己用了好几天了,迟迟没有发布出来就是担心大量应用后google估计就会修改google adsense代码了,还有就是我不知道这样做是不是违背了google广告的保留条款,仔细查看后发现有这样一条


Google 严禁以任何手段人为提高点击次数或网页展示次数,并通过工程系统和人工分析对行为进行密切监控。

 


所以希望大家只是拿来当技术研究,切勿长时间靠这个跟踪客户点击,虽然目前这个程序不影响任何adsense投放和点击后的动作和行为,但是如果有一天google的工作人员亲自上你的站点研究代码就全暴露了。我blog上的数据也统计了好几天,基本和google提供的统计数据差不多,因为我的blog上有用户留言的cookie,所以我特意保存了用户名,想看看每天都是谁在点击我的广告,统计后发现点击我广告的人都没在blog中留言,在blog中留言保存了cookie的用户从来不点击广告

本篇文章使用aigaogao Blog软件发布, “我的Blog要备份”