步入.Net时代,MS想让人们把网页开发当成应用程序一样开发,而且还在ASP.Net 2.0加了很多控件,像Loginform,Treeview等等。但在网页脚本语言(如ASP、PHP、Perl等)和J2EE还在继续占领着WWW大部分江山的情况下,如果只懂得写codebehide里的东东是远远不够的。 

  现在很多ASP.Net初学者居然都不知道何为JavaScript,或者只是听说过,而不甚了解。比如很多新手问这样的问题:如何用ASP/ASP.Net弹出一个对话框?尽管这对一个网页老手来说是轻而易举、嗤之以鼻的小事,甚至他们会大惑不解,连这都不懂还来编网页?这正是应用程序和网页的最大区别,网页是由HTML、CSS、客户端脚本、行为等等各种元素组成的复杂产物,因为不能与Web服务器保持实时连接,所以很多东西不能由服务器端来控制。我期待着MS将如何填补这道沟壑,希望在VS.Net2005正式版中能看到一些改变(一直在想MS是否有可能把弹出对话框做成一个控件或包装成Web.MessageBox类,呵呵)。VS.Net 2003中根本没看到对方便编写客户端脚本的支持,这又是出于怎样的考虑? 

  还有一个问题也是值得斟酌的:ASP.Net的提出应该是针对企业级用户的多层架构需求,而现在盲目地把它用于开发普通的网站,VS.Net默认产生的大量垃圾网页代码对于现在平均带宽以K计的中国(CNNIC2005年最新的统计报告表明拨号和ISDN占44.5%的用户数量,)是否过于累赘呢?不再强调使用CSS文件;不再强调使用SSI(Server Side Include);自动产生的一堆加密JS控制脚本;一旦编写不当动辄提交整个网页来获取少量的数据:这些无论对服务器还是客户都加重了负担……看来ASP.Net更需要知识全面缜密的程序员! 

posted on 2005-01-22 21:43 wonderow 阅读(344) 评论(15)  编辑 收藏
Feedback 
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-22 22:43 | 木野狐 
用的好的能在大幅度提高效率的前提下尽量减少性能损失和带宽浪费。 
用的不好的只能生产出垃圾,不管他用的工具是多么先进。 
这就是有思想和没思想的分别,也没什么可说的。
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 00:35 | wonderow 
嗯,不错 我是担心以后的ASP.Net程序员都不懂网页了…… 
btw: 搜索到过你写的一个围棋程序,但似乎没写完.不知道对于判断胜负(或者估算胜负)你有什么好的算法?呵呵
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 10:03 | Ariel 
关键还是看如何应用技术的问题吧,看看PetShop那里,把没有必要的页面的ViewState和SessionState都关闭了。 
实现是一回事,高性能开发又是一回事。支持大用户访问量门户站点的网站开发和企业级开发的思路是完全不同的。企业级应用的访问量一般都不是很大,带宽都是以MB计,而且要求界面复杂(SharePoint Portal Server就是好例子)。Visual Studio .net的代码模型恰恰都是为这些设计优化的。
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 10:19 | 勇敢的心 
技术是没有错 
只是因为ASP.NET进入门槛低 
所以缺乏高级程序员 
我个人看应该是人才和成本的问题
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 11:23 | kwklover 
我很喜欢微软的这种做法,他复杂的东西封装的很好,开发容易,效率高了,我们这些做web的就可以少点跟那些令人郁闷的javascript,vbscript,css,如果甚至连html,css,都不用考虑,那就更好了 

所以我很讨厌微软做的不够彻底,所以还需要会什么脚本,标记语言。 

技术无所谓好坏,都是用来满足社会需要的,反之,一切都没有价值的! 

期待新技术的出现,让一切标记,脚本语言都消失,它太浪费人的时间和精力了!
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 20:35 | 无 
我想就象做车和步行,当有汽车出现时候,走路的人得到了解放,虽然花了钱但是很值得,而现在 asp.net和asp就好象是公共汽车和私家车的类别,公车经济,但是不方便,私车方便但不经济
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 22:06 | bbpnb 
我的一个想法是,如果哪天开发web应用的程序员连javascript都看不懂了,那倒真是一个悲哀:要么是开发工具和开发语言的易用性做到极限了,“门槛”低得足够让以写程序为生的大伙失业了,要么是基于浏览器的web应用被淘汰了(也许有那么一天XAML或Smart Client完善和推广得让用户可以完全放弃基于浏览器的web应用了:))。 

前几天碰到一个朋友在ISP提供的支持asp.net的web服务器上发布自己的asp.net程序,结果发现本来很好用的程序发布了以后出现了很多奇怪的现象,(最典型的一个现象是calendar控件不好用了),我们一起分析了一下现象,从客户端代码的分析得出结论,是支持服务器控件的javascript脚本无效,最后我们不得不致信ISP,请他们检查一下\Inetpub\wwwroot\aspnet_client\system_web\是否还在,ISP的答复是他们前些天整理服务器,发现这个目录里只有几个.js文件,就把这些看起来无用的目录删掉了。其实正是这正是问题的原因所在,而导致出现这个“失误”的原因正是因为ISP对asp.net的基本常识没有正确的认识,对支持asp.net的工作原理没有了解。 

所以我的个人看法是,对于javascript,html, css, xml/xsl等基本原理的理解和认识是开发web应用程序能力的ABC,不论是基于asp.net, jsp, php, coldfusion, asp, cgi的web应用,如果看不懂javascript,就如同没学会走就学跑,或者没学会写正楷就去写狂草一样,是有待商榷的。
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 23:08 | kc 
错了,我认为作为web程序员并不一定要熟悉js,但应该知道js的存在以及其作用,我认为js是作为表示层方面的,个人更认为是美工应该掌握的语言,对于程序员应该关注的是业务流程,也就是处理数据为基础的。当然我认为asp.net目前在这方面还做的不够好,未能让程序员完全脱离js之苦。 不知道为什么,我就一直不想学js,做web差不多1年了
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-23 23:51 | wonderow 
呵呵,KC和bbpnb正代表着新老WEB程序员的观点。
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-24 00:39 | kc 
我有点奇怪了,大家好像觉得懂js的才是高级程序员,呵呵
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-24 02:06 | bbpnb 
呵呵,是老了。 
如果我再回答“我没错”,好像有点抬杠了,不过我想我依然有保留意见的权利。:) 

需要说明一点的是我同样认为大多数情况下,大多数web程序员不必十分了解javascript本身,以我本人为例,6年前做过cgi,后来做过php,然后一个做了3年的项目基于asp+com,2年前不得不升级到.net,可是却从来没有写过一个象“万年历”(in javasctipt)那么cool的程序,多数情况是需要的时候从网上或者自己的代码库中抄来改去,惭愧! 

关于“新技术”有一点想法,以asp.net为例,与之前的web开发技术相比,从开发效率和易用性上有了质的飞跃,我想起从前代码经常被客户打回来,理由常常是“程序在Netscape上没法工作”,或者“在Mac上显示不正常”,接着就得痛苦的查手册,改代码,测试,发布,然后等待新一轮的痛苦...而现在使用asp.net这些问题已经完全不是问题了(当然另一个重要原因是现在没多少人用netscape了:)),如何能不让人感慨。而另一方面,到目前为止,不论多高级的基于web的表示层架构,asp.net也好,struts也好,从原理上看,都没有发生质的变化,还不都是browser/server, http, html, javasctipt, css, request/response等等这些东西?asp.net的高级在于1. 开发工具高级, 生生的把stateless的web app的开发模式变成了vb-like的开发模式,简单得让人分不清哪些事情发生在client,哪些发生在server,让人弄不清楚"view source"里那一大串base64编码的viewstate有什么用,让人弄不清楚服务器上\Inetpub\wwwroot\aspnet_client\是不是垃圾;2. 类库高级,这当然要归功于.net framework,要不然以前在asp里用个regular expression都要大费周章;3. 编程语言高级,这点要归功于J2EE,要不是Microsoft觉得script+com和java比较起来实在有些寒碜,恐怕也不会凭空造出个带四个加号的C语言和被改的面目全非的Visual Basic; 4. server control高级,和前面几点比较起来,这一点显得并不重要,不过从应用角度看,正是server control让人觉得用asp.net使web应用的开发变得如同儿戏。 

说到server control,个人感觉其server-side功能固然强大,不过更让人佩服的是它把client-side技术无缝的结合到server-side,给人印象最深刻的是validator控件和calendar控件,asp.net把是否使用client-side代码的选择权留给了开发者,还会适应浏览器生成不同样式的客户端代码,这一点实在是牛。Microsoft的server control恐怕我们很难直接看到源码,不过博客园上可以找到D版的带源码的infragistic的web control :),从这些源码里我们可以看到大牛们是如何开发server control,说起来也简单,也不过是在开发server control的架构基础上加了写server端代码和client代码,也就是说不过是由一些C#代码和一些javascript代码组成的:)。话题又说回javascript,我想如果不是对客户端的javascript非常熟悉,如何能写出能在客户端对datagrid排序的功能?如何写出不刷新页面直接动态添加dropdownlist数据的功能?等等。当然有人说:“我可能从来也不用自己开发一个那么高级的server control,就像我学过操作系统原理但永远不会有机会去写一个操作系统一样”,当然这也是对的,不过既然献身给了这个轰轰烈烈的软件开发事业,就总得有点更高的精神追求不是?:) 

再说点其它废话,本人曾经被要求做一个web crawler,就是写个scheduled job,根据给定的url和参数去指定的web站点抓指定页面、解析、分词、存储、索引、查询,类似于搜索引擎做的那些勾当,当然搜索范围要小的多,不过数据挖掘的精度要求很高。当时非常头疼的一个地方就是要抓取的不同页面里包含了大量不同形式的客户端脚本,为了准确定位到一个指定页面的指定位置,不得不耐下性子一点点看这些javascript,遇到写得非常变态的代码也许就把活人憋死了。所以今天谈起学习javascript是否有用这个话题,就想起了这个例子,我想如果看不懂javascript的话,那所谓"web程序员"能做的工作就有很大局限性了。 

另外还想给javascript平平反,如果javascript只能作为“美工应该掌握的语言”,那有点太委屈了。就语言本身来说,Javascript的用途完全不只局限于浏览器里客户端代码的开发,其实个人认为在asp里使用jscript作为server-side的脚本语言要比vbscript更合适,另外Windows Scripting Host也支持javascript, 也就是说几乎可以用javascript在Windows系统上做任何事(包括坏事:)),MS在.net最早的版本里就把javascript改造成了javascript.net,可以开发基于.net framework的托管代码。不论作为脚本语言还是作为托管代码开发工具,javascript都有其特点和优势,作为脚本语言,javascript支持面向对象,支持不同浏览器,这些都是vbscript所不具备的特点;作为托管语言,它虽然没有C#那样严谨(强类型),不过这恰好成为它的一个优势,也就是所谓的"动态语言",现在Python,Ruby这样的动态语言也都在向.net靠拢,其实javascript正是一种Python那样具有动态特性的开发语言,(比如那个eval函数,实现同样的功能,用C#的reflection要麻烦多了),这也正是为什么MS早早的把javascript改造成.net开发语言的重要原因,为了弥补“动态语言”的空白吗。:) 

围绕javascript说了这么多,实在有点小题大做了,其实不仅javascript,就是web应用程序这个话题,也不过是企业级应用的一个组成部分而已,我们需要学习的东西太多了。至于“程序员应该关注的是业务流程,也就是处理数据为基础的”这个话题就更广泛了,俺也没资格在这里过多评论。 

借wonderow兄的帖子聊了这么多废话,还望见谅!:)
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-24 11:25 | wonderow 
嗯,很赞同bbpnb的一些观点,也许有些“废话”不得不说:) 
我觉得就是:懂JS未必是高级Web程序员,但不懂JS肯定不会是高级Web程序员
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-25 13:09 | jimjiang 
说到底还是因为用D版的不花钱, 所以才养成了动不动就拿高射炮来打文字的习惯, 人家的.Net根本不打算给一般的小应用来作,关键是面向服务, 如果都以为这个门槛低就来搞, 那才可怕呢. 
能用Excel就解决的东西非要搞几个程序员搞出个系统来. 这是中国特色, 也是为什么老是不把软件当钱的原因. 
说多了就小题大做了. 
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-26 02:26 | 问天 
做为一个web程序员,要是不懂javascript,他就不是一个web程序员了…… 
在开始学asp.net的时候,我是把它看作一个javascript生成工具的…… 
FreeTextBox应该是一个应用范围很广的asp.net控件…… 
但是,个人觉得,FTB的最精彩之处在于它的客户端javascript脚本……从1.6.3一直到现在的3.0,每个版本都对其javascript的做了彻底的升级……每次都很漂亮…… 
其实……我觉得……web程序员现在能够做的最精彩的东西是用前端javascript动态读取远程xml的方式做网站……gmail/csdn/msdn都在使用这样的方式,我想,是很能够说明问题的……
   
# re: ASP.Net的反思——网页中的服务器端和客户端脚本(一)2005-01-26 08:53 | 阮 
去看看Avalon吧,Web的时代就快要结束了。

 

一般介绍动态网页开发的资料都会机械式地先讲HTML,再则有空讲讲JS,然后切入正题讲动态网页部分,最后给出一些实例,比如留言板、论坛,甚至小型电子商务网站等等。而更新的ASP.Net甚至可能只从WinForm讲起,然后就讲WebForm了……这样更加使程序员无法接触底层的代码,无法理解整体架构和工作流程。我认为ASP.Net的出现有点像高级语言的诞生,高级语言的编译器实现了自动编译链接高级语言代码到汇编代码的过程,虽然最终的代码未必那么简洁,但毕竟经多重优化也在可接受范围内。而如今的ASP.Net原意想封装所有的客户端代码,实现从WebUI+CodeBehide到HTML的自动生成过程,但由于种种原因现在还做不到完全满足开发者需要(可以这么说,它产生的“汇编代码”不尽如人意),很多基本功能需要了解客户端脚本,进行手工修改才能实现。 
  正是ASP.Net现在所处的这种矛盾阶段,我们更有理由要掌握更多的知识,从HTML、CSS到JScript、behavior、XML。言归正传,本文将直接把服务器端脚本和客户端脚本放在一块讲述比较,这是极少有人做过的,也可以解开一些入门者的困惑,比如为什么服务器端脚本就是不能弹出一个对话框、弹出确定框、打开新窗口等等问题。再看看这二者到底管辖和作用了怎样的范围,然后再举例来认识一下如何使这两个脚本间可以交互,以实现更强的功能。 
 
按此在新窗口打开图片
图为早期PHP4的分层示意,虽然从现在的n层架构来看画得不甚清楚,但还是能看懂的。两个脚本很简单:顾名思义,一个运行在服务器端,一个运行在客户端。而它们的任务也很明确:服务器端脚本只用于生成网页代码(可以包括HTML、CSS、JS等等),它正是平常所说的ASP/ASP.Net、PHP、JSP等等,在动态网页中一般用“<%%>”、“<??>”等符号包围,在多层构架中也可以把Beans,CodeBehide等等算进去吧。客户端脚本就完全是在客户浏览器里解释运行的,要么在“<script>”中,要么在一些事件里,要么单独一个文件,总之查看源代码一般都可以看到,对最终浏览用户相对是公开的。它控制着用户与浏览器的交互,如果把浏览器看成应用程序,它的所有动作都是客户端脚本完成的,这就解释了为什么总是没有弹出对话框的服务器端函数。 
  因为ASP本身用的脚本与客户端脚本完全一样,都是JScript(或JavaScript)和VBScript,所以经常让初学者感到摸不着头脑,还有很容易使人混淆的<script runat="Server">这个标志。其实还是上面说的原则,用“<%%>”包围起来的代码肯定是服务器端脚本,当然还有<script runat="Server">里的(这不都标明了是运行在服务器端的嘛),这些代码经过Web服务器解释运行后在最后的HTML代码中肯定是找不到的。还有一点要明白的是,无论是JS还是VBS都可以用来写任何一端的脚本,只是一般比较习惯用JS来写客户端脚本罢了。至于一般用VBS来写服务器端脚本可能一个是习惯,一个是以示区别。 
  ASP.Net用RegisterClientScriptBlock()、RegisterStartupScript()等方法来在代码中添加客户端脚本,以及control.Attributes["event"]="script"来为控件添加事件处理脚本。懂得这些和一点JScript知识你也许知道如何实现在按个删除按钮之前弹出一个确认窗口了,把下面代码写在Page_Load里: 


btnDel.Attributes["onClick"]="return confirm('确定要删除吗?');"; 

  但如果你多懂得一点内幕,马上就会发现这样虽然能行,但是有很致命的副作用:如果同一页面中设有validator,尽管validator可以报告有错误的输入,但它们都不能阻止表单提交了!原因在于ASP.Net把你自己写的那段JScript代码写在了按钮onclick的最前面: 


<input type="submit" name="btnDel" value="Button" onclick="return confirm('确定要删除吗?');if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="btnDel" style="……" /> 

  这样原来的if语句后的那条就无法执行了,而Page_ClientValidate()正是ASP.Net自带的WebUIValidation.js里的函数,而一旦影响该函数的正常运行则会使表单不能按原定的方式判断提交。奇怪的是MS自身提供的范例也有这么做的。我们稍微更改一下onClick的脚本来获得正确的做法: 

btnDel.Attributes["onClick"]="if confirm('确定要删除吗?') return false;"; 可见客户端脚本的使用是无处不在的,有时需要熟练的技巧和敏锐的决策,在过去的ASP时代如此,现在的.Net时代亦不外如是。 


# re: 分清脚本——网页中的服务器端和客户端脚本(二)2005-01-24 20:19 | 奇思软件 
或许用我写的一个组件更方便:) 
此组件从标准button继承,但在提交之前显示提示框,依旧支持验证 

using System; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.ComponentModel; 

namespace Keyss.WebControls 

    [ToolboxData("<{0}:Button runat=server></{0}:Button>")] 
    public class Button : System.Web.UI.WebControls.Button 
    { 
        protected static string _warningScript = "if(!window.confirm('{0}')) return false;"; 


        [Bindable(true),  
        Category("Appearance"),  
        DefaultValue("")]  
        public string WarningMessage 
        { 
            get  
            { 
                object o = ViewState["_warningMessage"]; 
                return o==null?string.Empty:o.ToString(); 
            }
            set  
            { 
                ViewState["_warningMessage"] = value; 
            }
        }
         
        [ 
        Bindable(true), 
        Category("Behavior"), 
        DefaultValue(false) 
        ] 
        public bool EnableWarning 
        { 
            get  
            { 
                object o = ViewState["_enableWarning"]; 
                return o==null?false:(bool)o; 
            }
            set  
            { 
                ViewState["_enableWarning"] = value; 
            }
        }

         
        protected override void OnInit(EventArgs e) 
        { 
            base.OnInit (e); 
            if(this.EnableWarning) 
            { 
                string onClick = this.Attributes["onclick"]; 
                if(onClick == null) 
                { 
                    this.Attributes["onclick"] = string.Format(_warningScript,this.WarningMessage); 
                }
                else
                { 
                    this.Attributes["onclick"] = string.Format(_warningScript,this.WarningMessage) + onClick; 
                }
            }     
        }

    }
}

 


懂客户端脚本的未必是好的Web程序员,但只懂服务器端脚本或编程的肯定不会是好的Web程序员。至少在现今阶段,要写出高效Web网页或Web应用程序,不对这两个脚本充分理解熟谙于心是不行的。聪明的程序员能灵活使用脚本,对各种Web程序的业务流程得心应手。 
  比较常用的技巧是用服务器端脚本来写客户端脚本,这里用一个较流行的局部刷新的例子来展示该技巧。前提是对客户端脚本有较好的了解。 
  “<script>”标签有个属性src,其值可以设置为一个js文件,文件中即是客户端脚本。因为没规定该js文件是静态文件,而且可以用脚本来更改src指向的文件,所以可以巧妙地使用这个特性来实现动态局部刷新(当然,frame、iframe等也有src属性,均可考虑,这里用script方便一点)。这里有两个网页,一个test1.htm是主页面,而另一个test.asp其实是js文件,只不过它的内容是动态的。 
test1.htm 

<input name="txt" type="text" size="10" maxlength="10" /> 
<script id="s" src="test.asp"></script> 
</script> 
function func(){ 
  s.src="test.asp"; 
  txt.value=sTxt; 

setInterval("func()",1000); 
</script> 
 
test.asp 

//JScript 
<% 
response.cachecontrol="no-cache" ' 不使用缓存,确保页面更新 
sTxt=… ' 动态地获得一个值 
%> 
sTxt="<%=sTxt%>"; //注意这里两个sTxt,前一个是客户端,后一个是服务器端变量 
 
  这样在主页面test1.htm中每隔1秒就会看到文本框“刷新”一次,实现了局部刷新。把该技术加以扩展推广可以满足更复杂的需求。注意理解test.asp中的两个sTxt变量及两种注释方法,记住ASP是写在<%%>中的,是用VBScript写的,所以注释用单引号“'”;客户端脚本用JScript写的,所以注释用两个斜杠“//”。 
  这是服务器端脚本把变量传给客户端脚本的例子,如果还不明白就动手做做实验,在浏览器中输入test.asp地址看它到底输出了什么。至于客户端脚本把变量传给服务器端的例子就司空见惯,平常用得再多也不过了,如表单数据提交之前的简单处理再交给服务器就是一例,这里就不具体阐述了。所以也许在不知不觉中我们就在做着二个脚本之间的交互工作。 
  最近又看到有人用JS在客户端创建XMLHTTP组件来读网页来实现局部刷新,当然这种技术是无法跨平台的;还有Web Service、Remoting等技术来实现局部刷新,都是不错的主意,自从MS的JScript可以创建ActiveX对象,逐渐支持面向对象特性后,客户端脚本威力愈发强大。对我们来说,一旦分清楚服务器端和客户端脚本的辖区及作用,下功夫看些网页客户端脚本语言知识,善用脚本交互,就不难理清Web程序的思路,打开层层迷障,完成各种任务!