新手应该注意的ASP陷阱

放弃asp的时机也差不多了,末了,总结一些自己的经验,给还在asp中打混的新人。

老鸟应该都知道的了

一.编码问题.

一个asp文件中可以影响编码的大概有以下几处:

1)文件编码(指文本文件本身的编码,一般的编辑器状态栏都有显示,常见gb2312,gbk或utf-8,或big5,不知道的话可以用记事本打开文件,另存为,下面如果显示ASCII,那么文件就是本地编码,一般是gb2312,如果是unicode或utf-8,就是utf-8编码)

2)html的meta声明 meta http-equiv="Content-Type" content="text/html;charset=gb2312" (或charset=utf-8)

3)codepage 在文件的最开始处声明脚本类型和脚本页编码 @ LANGUAGE="VBSCRIPT" CODEPAGE="936"或CODEPAGE="65001"

这里65001代表utf-8,936代表gb2312

4)Response.Charset="utf-8"或"gb2312"

5)Session.CodePage=65001 这个影响不大,如果不放心,可以设定一下,编码和codepage一样,要用数字表示

这些编码统一之后,一般就很少出现乱码问题了。

二.下标越界

这是对于数组而言的。

vbscript的数组很麻烦,固定的数组长度不能变,动态数组变化的时候需要redim,如果要保留数据,还要加个preserve

不像jscript,直接给个下标就能赋值。也可以push,pop等.

定义定长数组还一定要用常量,不能用变量,如果非要用变量定义长度,那只能给动态数组定义。

无论是动态或者静态,只要下标不在范围内,都会出现下标越界的错误,这时候就要检查数组的长度和下标值了。

还有一种情况,如果数组是空数组,是没有下标的,用任何下标都会越界。

还有一点不得不说,asp的多维数组,很鸡肋,虽然也有不少人在用,但实在没有非用不可的必要。

我以前就常常被多维数组的下标搞昏了头,一般只用到二维,在于recordset返回时的二维数组,颠来倒去,不晕才怪。

三.ByVal和ByRef以及变量的声明

这两个声明是针对函数的参数的,ByRef意即按地址引用,此时如果在函数体内更改相应参数的值,调用时传的变量值也会改变。

就有可能影响到后期程序的运行。ByVal是按值引用,是将参数做一个拷贝传进来,在函数体内改变不会影响到传来时的参数。

vbs中的函数默认都是ByRef

这个问题其实比较像变量的声明问题,vbs允许不声明而直接给一个新变量赋值,但这个变量将成为全局变量,所以,建议写稍微复杂点的程序时都尽量先声明变量,特别是在函数体内,容易忽略的是循环体的变量如 i,j之类的。一些错误也常在此处发生

四.对象的默认属性.

vbs类声明里有一个default property get,这个属性允许调用该类的实例时不指定属性,而默认使用这个属性。当然这只是类的一个特性,应该是好的,然而asp的一些原生对象或引用对象也具有相似特性,下面仅列一些相似特性的对象

request.querystring

request.form

request.servervariable

dictionary

recordset

....

好像到处都是,正因为此,一些对asp特性不了解的新人常常会误解,把本该是对象的,误认作字符串,这在vbs中当然一般不会出问题,但一旦转型语言,问题就来了。

最简单的,判断querystring中 a是否有值,在aspvbs中可以直接这样写

If Request.QueryString("a")="" Then ...

但改用jscript呢

if(Request.QueryString('a')==''){...}

是不行的,它总不等于空,为什么呢

Response.Write(typeof Request.QueryString('a'))

发现了没,它是一个对象,并不是字符串,那为什么在vbs中它就是字符串呢?

vbs中对象和普通变量是有区别的,对象赋值需要用set关键字,而普通变量,只要用 = 就可以了

所以当用=将一个对象赋给变量时,默认会调用对象的转换字符串的方法,这里调用了item()属性.

不信可以试试在asp中

set vara=Request.QueryString("a")

是不会出错的,而用常量或其它变量放到等号后,便会出现缺少对象的错误.

item是很多asp原生对象的默认属性.这一点一定要记住.

有一个例外,就是recordset

它的默认属性是fields(不太准确,姑且这么理解)

我们写的最多的 rs("id"),实际应该写成 rs.fields("id").value

value就是field对象的默认方法,给它展开了,确实太长了。但这是asp的特性,没办法,只能在vbs中简写使用,换了其它语言,常常容易出错。

像jscript,赋值的时候是不管对象不对象的,最容易出现的问题是把field对象赋给一个变量,而还误以为赋的是string值,这就会在recordset关闭以后,出现数据源丢失的现象.

 

五.Request.BinaryRead

这个对象一般写上传类时才会用到,我就是学习python时,用python写asp上传功能时发现的这个陷阱.

Request.BinaryRead返回的其实是一个数组,二进制就放在第一个元素,至于会不会有其它情况,我还没有发现。

在vbs写的上传类时,一般直接将这个数组以二进制写入到stream对象,所以,不会关心它返回的原型。我也是用python处理时报错,于是查了下手册,才知道它返回的是一个数组,在python里其实是tuple

手册原话是这样写的:

variant = Request.BinaryRead(count)

 

 

variant
包含由该方法返回的无符号数的数组。该参数的类型为 VT_ARRAY | VT_UI1。
count
在执行前,指定要从客户端读取的字节数。此方法返回后,count 将包含从客户机成功读取的字节数。实际读取的字节总数将小于或等于 Request.TotalBytes

 

暂时记下这些,以后想到再写。

手册是个很有用的东西,很多事情搞不明白了去看下手册,也许就愰然大悟了.