分享
 
 
 

ASP 3.0高级编程(三十二)

王朝asp·作者佚名  2006-12-16
窄屏简体版  字體: |||超大  

7.2.4 客户端脚本错误

到目前为止,我们已了解了来自ASP的错误。然而ASP也经常用于创建包含客户端脚本的网页。如果包含客户端代码的<SCRIPT>元素没有被设置成RUNAT="SERVER"属性,ASP将不考虑服务器,而把网页信息不加改变地传送到客户端。

因此,如果打开了一个ASP网页,并且显示的是一个浏览器错误对话框,就不应该在服务器端寻找ASP程序代码的错误。浏览器看不到ASP程序代码,所以不能识别任何错误,如果有一个对话框出现在客户端,那么在客户端代码中必定有一个错误。

1. 语法错误

如果在网页中的客户端程序代码有语法错误的话,当脚本下载到客户端,浏览器便会出现相应的错误。尽管网页中内容仍可正常载入(除非由这些客户端脚本代码动态装入),但网页停止执行。用户将看到一个包含错误细节的对话框,或者是一个指示网页包含错误的状态条消息。

现代浏览器趋向于隐藏网页脚本错误的细节,而仅在状态条上显示一个小的错误图标。在IE 4.0和IE 5.0中,正常的错误对话框可以通过Internet Options对话框的Advanced页进行设置来激活

处理脚本程序代码中的客户端错误和在服务器端相似,并且通常会更容易些,因为经常可以直接从服务器目录中通过双击来下载网页。一般不需要通过Web服务器和HTTP获得网页来观察浏览器中的结果,其中的唯一不同是一些服务器交互由客户端脚本来完成,如使用RDS的数据绑定或者动态装入。

2. 运行期或语义错误

在客户端脚本中,通常可能会遇到语法错误,也会经常遇到运行期或语义错误。事实上,在客户端,这种现象是很普遍的。因为在客户端不能像服务器端那样对脚本的环境进行控制,不能肯定用户在他们的机器上正运行什么,实际上在服务器上仅能从一些组件如Browser Capabilities中得到大概情况。

所以,使用客户端对象或特殊版本的脚本语言和属性的脚本程序很可能不能正常工作。尽管如此,处理客户端错误和处理服务器端错误是差不多的。

3. 在服务器上创建的客户端程序代码

在错误发生时,作为“客户端对话框对应于ASP错误页面”规则(关于出错的地方)的一个特别的例外是,使用ASP程序代码在服务器上动态地创建客户端程序代码。例如,可能想在ASP中进行求值运算,然后把数据传给运行在客户端的脚本代码,可能最容易的方法是把数据作为一个变量插入脚本代码中:

<%

' get the name of our server from the ServerVariables collection

strServerNameInASP = Request.ServerVariables("SERVER_NAME")

%>

<SCRIPT LANGUAGE="JScript" RUNAT="CLIENT">

<!-- hide code from older browsers

var strServerName = "<% = strServerNameInASP %>";

alert('Server name is: ' + strServerName);

// stop hiding code

-->

</SCRIPT>

在客户端,在ASP处理这个页面之后,将得到的是:

<SCRIPT LANGUAGE="JScript" RUNAT="CLIENT">

<!-- hide code from older browsers

var strServerName = "WROXBOX";

alert('Server name is: ' + strServerName);

// stop hiding code

-->

</SCRIPT>

可以忽略RUNAT="CLIENT"属性,但是加上这一项可以使得在查看运行代码的ASP网页时更加清楚。

这样,如果在某个位置想把服务器端数据库中的数据加入到一个客户端数组中,可以采用下面的程序实现:

<SCRIPT LANGUAGE="JScript" RUNAT="CLIENT">

<!-- hide code from older browsers

var arrBooks = new Array(10) //highest available index will be

<% ' start of ASP processing

intIndex = 0

Do While { not at the end of some recordset }

strTitle = { get title from database record }

Response.Write "arrBooks[" & CInt(intIndex) & "] = '" _

& strTitle & "'; " & vbCrlf

intIndex = intIndex +1

{ move to next record in database }

Loop

do something here on the client with the array of book titles

// stop hiding code

-->

</SCRIPT>

这段服务器端ASP程序代码产生的客户端代码,在客户端运行时创建书名标题数组。同时产生的客户端脚本错误出现在浏览器的错误对话框中。错误的原因是以arrBooks命名的数组是由JavaScript代码运行在客户端时创建的,仅能接受9个书名;而服务器端代码能很可能产生多于9个的书名,具体多少由源数据库中的记录数来决定。这相当于如下客户端代码:

<SCRIPT LANGUAGE="JScript" RUNAT="CLIENT">

<!-- hide code from older browsers

var arrBooks = new Array(10) //highest available index will be

arrBooks[0] = 'Instant JavaScript';

arrBooks[1] = 'Professional ASP 3.0 Programming';

arrBooks[2] = 'ADO 2.5 Programmers Reference';

etc

arrBooks[9] = 'ASP Techniques for Webmasters';

arrBooks[10] = 'ASP Programmers Reference'; // <- client-side error occurs here

arrBooks[11] = 'ADSI CDO Programming';

arrBooks[12] = 'Professional MTS and MSMQ Programming';

do something here on the client with the array of book titles

// stop hiding code

-->

</SCRIPT>

这个页面只有经过修正之后才能正常工作,可以通过增加数组大小,也可以通过控制来自数据库的记录数使其正常工作。

7.3 防止错误

上面已经看到了能够出现的一些不同类型的错误,并且有了一些查找错误的感觉。下面将考虑如何避免把错误引入程序中,尽管不能保证所编写的程序没有错误,但是这里概括的许多技术有助于减少错误数目。

良好的编程习惯

在编程中避免出现错误是和良好的编程习惯相关的,这里有许多工作我们要做,以减少把错误带进网页的可能性。可能有些人因采用某个技术而走向极端,甚至一定程度上在某个特殊问题上因书生气十足而引入了更多的错误。当然编程人员也不可能采用了这里列出的所有技术。

要考虑的主要内容是:

· 代码的格式化和缩进编排。

· 变量显式表明。

· 变量转换为合适的数据类型。

· 使用有意义的变量命名约定。

· 封装脚本。

· 注意潜在的错误情况。

1. 代码的格式化和缩进编排

许多VBScript编程员懒于格式化编排其书写的程序。尽管这并不阻碍程序运行,但这使得查找何处产生了错误变得困难。例如,在前面我们看到的程序中,丢失了一个End If,由于嵌套结构的缩进,错误在哪里是相当明显的:

objCounters.Remove strCounterName

Response.Write "Removed counter " & strCounterName

<--- missing 'End If' should be here

End If

End If

%>

如果程序看起来像下面所示的那样,寻找错误将不是一件易事:

<% if Len(Request.Form("cmdSet")) then

strCounterName=Request.Form("lstSet")

strNewValue=Request.Form("txtSet")

if isnumeric (strnewvalue) then

intNewValue =cint(strNewValue)

objCounters.Set strCounterName, intNewValue

Response.write "Set counter" & strCounterName &" to " & strNewValue

else

Response.write strNewValue &" is not a valid number"

If Len ( Request.Form ("cmdRemove")) then

StrCounterName = Request.Form("lstRemove")

objCounters.Remove strCounterName

Response.write "Removed counter "& strCounterName

end if

End IF

%>

||||||2. 显式表明变量

VBScript支持Option Explicit语句。在一个脚本页面的开头插入Option Explicit语句时,可以避免使用没有用Dim命令(或用于动态数组的ReDim)定义的变量。似乎不需要这么做,因为脚本语言允许通过给一个变量赋值来创建一个需要的变量。然而用Option Explicit进行定义有助于避免错误,特别是那些难以发现的引起脚本产生不正确结果的逻辑错误。

例如,编写如下程序:

<%

' get value for calculation

strSalesTotal = Request.Form("SalesTotal")

curSalesTotal = CCur(strSalesTotal)

sngCommissionPercent = 2.5

' calculate commission payment

sngCommission = curSalesTotal * (sngComissionPercent /100)

%>

运行这段程序不会产生错误(当然,除非用户给销售合计值赋了非法的值)。然而这段程序总是会产生0的结果,因为在程序的最后一行中sngCommissionPercent变量名拼写错了。脚本解释器将产生一个新的变量名(叫作sngComissionPercent),由于没有赋值,在数学计算时返回值总为0。

为了防止这种错误,仅需在程序开头增加Option Explicit语句。

<%

Option Explicit

Dim strSalesTotal

Dim curSalesTotal

Dim sngCommissionPercent

' get value for calculation

strSalesTotal = Request.Form("SalesTotal")

curSalesTotal = CCur(strSalesTotal)

sngCommissionPercent = 2.5

' calculate commission payment

sngCommission = curSalesTotal * (sngComissionPercent /100)

%>

这时,当脚本引擎试图解释程序时将识别出一个语法错误,并且能够指出此变量没有声明

在JScript中引用一个没有声明的变量将返回一个“Undefined”信息,并且在试图使用变量之前,能够检测到这种情况。

3. 变量转换为合适的数据类型

回头看看前面的程序,可能发现用CCur函数把用户提供的数据转换成了货币型数据类型。在VBScript中,有一系列类似这样的数据变形变换函数,在第3章中有详细的描述。

blnBoolean = Cbool(varVariant) ' converts to a Variant of subtype Boolean

bytByte = Cbyte(varVariant) ' converts to a Variant of subtype Byte

curCurrency = CCur(varVariant) ' converts to a Variant of subtype Currency

datDate = CDate(varVariant) ' converts to a Variant of subtype Date

dblDouble = CDbl(varVariant) ' converts to a Variant of subtype Double

intInteger = CInt(varVariant) ' converts to a Variant of subtype Integer

lngLong = CLng(varVariant) ' converts to a Variant of subtype Long

sngSingle = CSng(varVariant) ' converts to a Variant of subtype Single

strString = CStr(varVariant) ' converts to a Variant of subtype String

如果不能完成变换,也就是说变量内容对新数据类型来说是无效的,便会出现一个运行期错误。然而,如果对数值类型进行变换,我们希望这个数值是有效的,并且能在程序中使用。因此能够检测一个均衡的值对于防止错误的出现是一件“幸事”。

如果想把输入空格作0对待,并且把任何其他无效的输入作为用户错误对待,前面程序变为:

strSalesTotal = Request.Form("SalesTotal")

If Len(strSalesTotal) = 0 Then

' no value entered, so assume zero

curSalesTotal = 0

ElseIf Not IsNumeric(strSalesTotal) Then

' not a valid number, so report an error and stop

Response.Write "The value you entered is not a valid number. "

Response.Flush

Resonse.End

Else

' OK to conver the string value and use it

curSalesTotal = CCur(strSalesTotal)

End If

在JScript中,所有的变量都是对象,并且有typeOf()方法。可以使用typeOf()来确定存在变量中的数据是什么类型,见第3章中的详细论述。

也可以对“null”(VBScript中为Null)进行测试保证在程序使用各种变量之前它们已经赋了值。一个特例是从数据库中获得数据时,数据库中的字段内容经常是Null,表示没有数据。

4. 变量命名和编码约定

阅读过本章和前面几章后,读者可以看出我们对变量名使用三个字母的前缀,用以指明它所代表的数据类型。尽管在这两种脚本语言中用ASP提供的所有变量都是Variant(或JScript中的等价物)类型的,但用变量名来区分出存储在其中的数据的类型仍是非常有用的,有助于防止编写程序时出错。

变量类型

前 缀

布尔型(Boolean)

bln

字节型(Byte)

byt

日期/时间型(Date/Time)

dat或dtm

集合型(Collection)

col

双精度型(Double)

dbl

整型(Integer)

int

长整型(Long)

lng

对象型(Object)

obj

单精度型(Single)

sng

字符型(string)

str

对于一个包含函数和子程序的网页,指出某个变量是否已经声明或存在于任何函数和子程序之外是非常有用的。若已经声明,则该变量对网页来说是全局变量。对全局变量加上“g”前缀,所以一全局字符串变量可能被命名为gstrMystring;类似的,以“a”为前缀的变量是数组或数组元素。

程序注释

许多编程人员感觉到对程序增加注释不仅增加了不必要的开发时间,而且也减缓了网页的运行速度,因为脚本解释器每次必须先读整个程序,然后再跳过这些注释。尽管这种观点有一定的道理,但是一个月后再回过头来想读懂没有注释的程序,是非常困难的。

至少应该对常用函数和子程序进行注释以便你和其他人能重新使用这些程序。特别是,使用新的Server.Execute方法更加容易(详细情况参阅第4章)。下面是微软提供的一个例程的注释格式。

'*****************************************************

'Purpose: what the routine is designed to achieve

'Inputs: a list of all the parameters to the routine

' parameter1: description, data-type, etc.

' parameter2: description, data-type, etc.

'Returns: what data type is returned, and what it contains

'Comments: other comments about the routine, update history, etc.

'*****************************************************

5. 封装脚本语言以便代码重用

刚刚看到了如何注释子程序和函数以便易于重新使用。面向对象编程的原理是建立在程序代码重用的基础上的,并且SSI的#include和新的Server.Execute方法使调用存储在程序库中的函数更容易。

例如,如果有一系列函数用于计算税收和商品的应付费用。可把包含这段程序的页面插入其他页面中:

<!-- #inculde VIRTUAL="/library/code/online_sales/tax_and_delivery.inc" -->

包含文件必须含有脚本定界符,或者用<SCRIPT RUNAT="SERVER">...</SCRIPT>或者用<%...%>,每一个子程序和函数应该采用其要求的数值做参数,并且用函数值或更新的参数返回结果。不能使用全局变量,况且不同网页之间的全局变量也是不可用的。但在主网页中的程序能安全地调用所需的函数和子程序。

另外可使用Server.Execute(或者Server.Transfer)把执行转到另一个网页。如果有一段ASP代码用来为客户创建在线采购一览表,这种方法是非常有用的。它包含HTML用来创建标题、表格,用代码进行计算并用Request集合的内容填写相应值(记住不能使用Server.Execute或Server.Transfer把脚本变量传到另一个网页)。另外,运行的网页能够支持

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有