新手应该注意的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。
暂时记下这些,以后想到再写。
手册是个很有用的东西,很多事情搞不明白了去看下手册,也许就愰然大悟了.