一份代码编写标准

时间:2020-11-28 15:06:06
一、通用源代码格式规则
1.1 开发工具

 

推荐使用Microsoft  公司的Visual InterDev 来书写ASP 代码,使用Macromedia ? 公司的Dreamweaver 来书写HTML代码,也可以使用UltraEdit、ASPEdit 2000等开发工具。

1.2 缩进空格

缩进空格是指在每一级有两到四个空格。不要在源代码中保留TAB字符,这是因为TAB字符会随着不同用户的不同设置和不同的资源管理工具(打印、文档、版本控制等)而代表不同的宽度。

1.3 数据合法性检查

所有表单提交页面中,表单上必须填写项目和填写项目中非法输入的判断都在页面中用javascript在客户端判断,如果必须和服务器端数据比较才能判断输入项目是否正确不在此例。
所有提交的信息(GET方式及POST方式)都必须在服务器端重新进行数据合法性校验,并过滤非法字符(& ; ` ' / " | * ? ~ < > ^ ( ) [ ] { } $ /n /r),例如,将"'"替换成"''" (两个单引号)号(替换字符串的工作将统一使用公共的CheckInputString(str) 函数);而对于数字型变量,要检查输入的数据是否全为数字(javascript中使用isFinite或isNaN, VbScript中使用IsNumeric)。

1.4 参数传递

建议使用POST方法,而不推荐使用GET方法;
严禁使用GET方法、SESSION或其它方式传递SQL语句;
禁止使用GET方式传递大量的查询字符串,特别是未经编码的汉字,HTTP协议传送表单域比查询字符串效率要高,而且带有一个大的查询字符串的页面在某些浏览器上会失效;
禁止使用SESSION、COOKIE传递非会话期间必要的参数。

1.5 URL

包含头文件,页面的链接,提交的页面,用到的图片,如果引用的是如"include"、"image"等公共部分,必须使用绝对路径,即以虚根目录"/"开始的路径,以提高运行效率。例如:

6.4 使用最简单的游标类型和记录锁定方式

在 ADO 中定义了四种不同的游标类型:
l动态游标(adOpenForwardOnly) - 用于查看其他用户所作的添加、更改和删除,并用于不依赖书签的 Recordset 中各种类型的移动。如果提供者支持,可使用书签。
l键集游标(adOpenKeyset) - 其行为类似动态游标,不同的只是禁止查看其他用户添加的记录,并禁止访问其他用户删除的记录,其他用户所作的数据更改将依然可见。它始终支持书签,因此允许 Recordset 中各种类型的移动。
l静态游标(adOpenDynamic) - 提供记录集合的静态副本以查找数据或生成报告。它始终支持书签,因此允许 Recordset 中各种类型的移动。其他用户所作的添加、更改或删除将不可见。这是打开客户端 (ADOR) Recordset 对象时唯一允许使用的游标类型。
l仅向前游标(adOpenStatic) - 除仅允许在记录中向前滚动之外,其行为类似动态游标。这样,当需要在 Recordset 中单程移动时就可提高性能。

在打开 Recordset 之前设置 CursorType 属性来选择游标类型,或使用 Open 方法传递 CursorType 参数。部分提供者不支持所有游标类型。请检查提供者的文档。如果没有指定游标类型,ADO 将默认打开仅向前游标。

在 ADO 中定义了四种不同的游标类型:
ladLockReadOnly - 默认值,只读。无法更改数据。
ladLockPessimistic - 保守式记录锁定(逐条)。提供者执行必要的操作确保成功编辑记录,通常采用编辑时立即锁定数据源的记录的方式。
ladLockOptimistic - 开放式记录锁定(逐条)。提供者使用开放式锁定,只在调用 Update 方法时锁定记录。
ladLockBatchOptimistic - 开放式批更新。用于与立即更新模式相反的批更新模式。

打开 Recordset 前设置 LockType 属性可指定打开时提供者应该使用的锁定类型。读取该属性可返回在打开的 Recordset 对象上正在使用的锁定类型。Recordset 关闭时 LockType 属性为读/写,打开时该属性为只读。

在实际使用过程中应该使用适合于处理任务的最简单的游标类型和记录锁定方式。例如:

仅打开一个静态的记录集并输出:
Rs.Open sql,Conn,0,1 ' adOpenForwardOnly, adLockReadOnly
打开的记录集中有text类型的字段:
Rs.Open sql,Conn,1,1 'adOpenKeyset, adLockReadOnly

6.4 SQL字符串过滤

所有的字符串输入框在向数据库提交查询、插入、删除或修改一条记录时必须用字符串过滤函数检查,即:
字符型:复写提交内容中的"'"、"''"等(使用公共函数的CheckInputString()。),并检查字符串的长度是否超长。
数值型:使用IsNumeric()判断输入是否为数字。
整 型:使用Int(), Fix(),Round() 截取其整数值。
日期型:使用isDate()函数判断是否为正确的日期输入。

6.5 SQL事务执行

对数据库操作的事务一般应当使用SQL的存储过程执行。对于需要在ASP页面中执行的数据库操作,所有插入、删除、修改数据库不得使用RecordSet对象,必须使用Connect对象用SQL语句执行,RecordSet只在执行查询时使用。所有检索数据库的操作禁止使用"SELECT * FROM …",而要使用"SELECT 字段一, 字段二, 字段三, … FROM…"。

6.6 ADO对象的关闭

所有连接数据库页面中,Connect和Recordset等ADO对象必须在用完后立即关闭(Close),然后将其对象释放(Set ***=nothing)。

 

七、Cookies
7.1 Cookies的作用域

Cookies的Path属性规定了Cookies返回服务器的具体路径。为了使Cookies能够在整个网站的各个目录都可以起作用,应将Domain域属性设为:"/",
Cookies的Domain域属性限制了cookies可由浏览器送达之处。为了使cookies能够在整个网站的各子站点都可以起作用,应将Domain域属性设为:".yourDomain.com"。该值将作为常量cookie_Domain放入站点的公共文件中。即:

Response.Cookies("UserName").Path="/"
Response.Cookies("UserName").Domain= cookie_Domain

7.2 Cookies的有效期

Cookies的Expires属性规定了Cookies的结束作用时间。如果要建立一个会话期间的cookies,即要在客户结束浏览后失效,则一定不能设置该属性。

7.3 Cookies的安全

Cookies内部的敏感信息必须加密,该加密方式在公共密钥函数库中定义。

1.5 URL
包含头文件,页面的链接,提交的页面,用到的图片,如果引用的是如“include”、“image”等公共部分,必须使用绝对路径,即以虚根目录“/”开始的路径,以提高运行效率。例如:
<A HREF="/index.asp">
<IMG SRC="/images/logo.gif”>

在一个相对独立的模块内部,可以使用相对路径,以提高可移植性。但是,禁止使用“..”返回上一级目录,即禁止使用类似“../images/logo.gif”的URL。相对路径如下书写:
<A HREF="index.asp">
<IMG SRC="images/logo.gif”>

确保在指向目录的 URL 中使用后斜杠 (/)。如果您省略了后斜杠,浏览器就会向服务器发出请求,只是为了告诉服务器,它在请求目录。浏览器就会发出第二个请求,将斜杠附加到 URL 后面,只有此后,服务器才能以该目录的默认文档或目录列表(如果没有默认文档且启用了目录浏览的话)响应。附加斜杠可省去第一个、无用的住返。为便于用户阅读,可以省略显示名称中的后斜杠。
例如,写:
<A HREF=http://msdn.microsoft.com/workshop/” TITLE=”MSDN WebWorkshop”>http://msdn.microsoft.com/workshop </A>
这也适用于指向 Web 站点上主页的 URL:使用下面的:<A HREF=http://msdn.microsoft.com/”>,而不使用 <A HREF=http://msdn.microsoft.com”/>。

1.6 日期

在使用、判断和显示日期时,一定要确定年为4位。统一定义为
长日期格式为: XXXX年XX月XX日
短日期格式为:XXXX-XX-XX
在ASP输出时必须使用FormatDateTime()函数进行格式化,前端输入时统一使用XXXX-XX-XX格式,并在后端使用isDate()进行检验。

二、HTML
2.1 标记

HTML 对大小写不敏感,但为改善可读性,规定大写所有标志、属性,小写属性值,属性值外必须加引号,如:<TABLE BORDER=”0” CELLSPACING=”0” CELLPADDING=”0” ALIGN=”left”>

2.2 META 标记

所有中文页面,必须在“<HEAD> … </HEAD>”头中加入如下META标记:
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=GB2312">
该META标记描述本页使用的语言。浏览器根据此项,就可以选择正确的语言编码,而不需要读者自己在浏览器里选择。GB2312是指简体中文,ISO-8859-1是指英文,而*BIG5内码的主页则是用BIG5。

在首页和各频道首页应加入如下META标记:
<META NAME="keywords" CONTENT="yourkeyword">
  <META NAME="description" CONTENT="your homepage's description">
  该META标记声明本页的关键字和描述。在页面里加上这些定义后,一些搜索引擎就能够让读者根据这些关键字查找到你的主页,了解你的主页内容。

在每次都需要重新生成的,不需要用户缓存的页面,应加入如下META标记:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
该META标记强制性调用网上的最新版本。浏览器为了节约时间,在本地硬盘上保存一个网上文件的临时版本。在你要重新调用时,直接显示硬盘上的文件,而不是网上的。如果你想让用户每次都看到最新的版本,就加上这句话。

2.3 统一样式表引用

为了使整个网站的风格样式统一,必须统一使用公共的层叠样式列表,即在每个HTML文件的“<HEAD> … </HEAD>”头中加入:
<LINK REL="stylesheet" TYPE="text/css" HREF="/style/default.css">

如果项目相对比较独立,应该使用自己的CSS定义,增加可移植性。

2.4 TITLE设定

所有中文页面TITLE设置需遵照如下标准:
YourDomain.com+空格+本页内容描述

所有英文页面TITLE设置需遵照如下标准:
YourDomain.com+空格+ -+空格+本页内容描述

2.5 表单

2.5.1 文本框:文本框(<INPUT TYPE=”text” NAME=”” …>)的宽度(SIZE属性)以数据库中相对应的字段长度为参考,并参照邻近文本框的宽度,以美观为原则确定;文本框的最大内容长度(MAXLENGTH属性)以数据库中相对应的字段长度为标准确定。

2.5.2 表单提交:必须使用POST方法,而不允许使用GET方法。

2.6 表格

2.6.1 高度和宽度的定义:应直接在单元格属性内用象素数定义,尽量不要用百分比定义,也不要用空白图去撑这个单元格。如特殊情况要求,只宜用百分比对单元格指定宽度,因为Netscape不支持百分比定义的高度。

2.6.2 空单元格:所有需要指定背底色或边框色的空单元格请一定要在该单元格内插入 ,如果该单元格的高度<9或宽度<5时,请用img目录下的none.gif。无背底色和边框色的空单元格,仅仅是用来定位时,请这样写:<TD HEIGHT="??" WIDTH="???"></TD>

2.7 图片

<IMG>标签必须使用WIDTH和HEIGHT属性来定义图片的尺寸,以加快浏览器显示页面的速度。对于一般的非占位用的图片,必须使用ALT属性来定义其文本显示。

2.8 注释

使用注释声明每一子块区的开始和结束,注释语句使用英文。如:
<!— User Login In Zone -->

 

三、javascript
3.1 标记
javascript是一种对大小写敏感的语言,语言的关键字按照javascript的要求书写,关键字小写,函数、对象使用固定的大小写。

3.2 函数/过程

用户自定义的函数应放在文件的<HEAD></HEAD>部分,以确保用户在与页面其他部分进行交互之前,所有函数都已装载,且准备就绪。页面加载时的动作也应写成函数/过程,在BODY的OnLoad事件中触发。

3.3 字符串串联

避免在循环语句中使用字符串串联。
建议使用+=运算符,即,使用s += ”某字符串”,而不要使用s = s + ”某字符串”。

3.4 事件处理器

事件处理器嵌在HTML标记之中,应声明脚本类型,如:onMouseOver=”java script:window.status=’大家好’;return true”>

3.5 注释

使用“//”来注释后面一行内的语句,使用“/* …… */”来注释成块的语句。另外,脚本要使用HTML的注释标记“
</SCRIPT>

四、VbScript
4.1 常量/变量、函数/过程的命名

常量和变量命名应以代表其含义、功能的单词组成,每个单词的开始字母大写,其余字母小写,循环变量i,j,k可以例外。对于频繁使用的或长的项,推荐使用标准缩略语以使名称的长度合理化。
对于变量来说,如果该变量是一个过程级(过程,子过程或函数过程中的)的变量,应在其前面使用“m_”的前缀来表示它是一个局部变量。例如: m_blnCalcInProgress。局部变量应单独在函数或过程中定义。
应该给变量加前缀来指明它们的数据类型。按照处理变量的方式(而不是其实际数据类型)在 ASP 代码中声明变量。例如:
前缀 使用的变量 变量示例
bln Boolean blnSuccess
cur Currency curAmount
dbl Double dblQuantity
dat Date and Time datDate
flt Float fltRatio
lng Long lngMilliseconds
int Integer intCounter
str String strName
arr Array arrUsers()
obj COM Object objPipeline

函数及过程的命名应遵循以上基本规则,并以一个动词起首

4.2 语句

大写或首字母大写IF, THEN, ELSE和END IF等VBScript语句。

4.3 字符串连接

为保持一致性并达到更有自述性的脚本目标,使用字符串连接符(&)代替加号(+)。

4.4 注释

使用注解解释难以理解的或复杂的代码。行内注释应该在相应代码后面显示两个空格。在新的一行上开始的注释应该与前一行对齐。建议使用单引号 (')代替 Rem 关键字,在没有代码的行上加注释可以使用Rem 关键字。注释语句尽量使用英文。

六、数据库&ADO操作
6.1 Unicode数据类型
数据库中有可能使用汉字的地方要使用Unicode的数据类型,即使用nChar、nVarChar、nText类型。

6.2 数据库连接

所有连接数据库的页面必须包括连接数据的头文件connAAAAA.asp(如果需要不同的连接文件,AAAAA代表不同的模块)。在该文件中定义使用 OLEDB 提供者连接数据库的连接串(不允许使用数据库管理员sa)。该文件将不放置在站点目录之下,使用“include file”的方式访问。
通过 OLEDB 使用 SQL SERVER ,使用下面的语法:

Provider=SQLOLEDB.1;Password=mypassword;Persist Security Info=True;User ID=myuid;Initial Catalog=mydbname;Data Source=myserver;Connect Timeout=15

如果要使用数据构形,OLEDB的连接使用下面的语法:

Provider=MSDataShape; Date Provider=SQLOLEDB.1;Password=mypassword;Persist Security Info=True;User ID=myuid;Initial Catalog=mydbname;Data Source=myserver;Connect Timeout=15

6.3 ADO 属性常量的引用

如果需要使用ADO常量,应将下面的代码加入该文件中,即可直接访问所有的 ADO 常量:

6.4 使用最简单的游标类型和记录锁定方式

在 ADO 中定义了四种不同的游标类型:
l动态游标(adOpenForwardOnly) — 用于查看其他用户所作的添加、更改和删除,并用于不依赖书签的 Recordset 中各种类型的移动。如果提供者支持,可使用书签。
l键集游标(adOpenKeyset) — 其行为类似动态游标,不同的只是禁止查看其他用户添加的记录,并禁止访问其他用户删除的记录,其他用户所作的数据更改将依然可见。它始终支持书签,因此允许 Recordset 中各种类型的移动。
l静态游标(adOpenDynamic) — 提供记录集合的静态副本以查找数据或生成报告。它始终支持书签,因此允许 Recordset 中各种类型的移动。其他用户所作的添加、更改或删除将不可见。这是打开客户端 (ADOR) Recordset 对象时唯一允许使用的游标类型。
l仅向前游标(adOpenStatic) — 除仅允许在记录中向前滚动之外,其行为类似动态游标。这样,当需要在 Recordset 中单程移动时就可提高性能。

在打开 Recordset 之前设置 CursorType 属性来选择游标类型,或使用 Open 方法传递 CursorType 参数。部分提供者不支持所有游标类型。请检查提供者的文档。如果没有指定游标类型,ADO 将默认打开仅向前游标。

在 ADO 中定义了四种不同的游标类型:
ladLockReadOnly — 默认值,只读。无法更改数据。
ladLockPessimistic — 保守式记录锁定(逐条)。提供者执行必要的操作确保成功编辑记录,通常采用编辑时立即锁定数据源的记录的方式。
ladLockOptimistic — 开放式记录锁定(逐条)。提供者使用开放式锁定,只在调用 Update 方法时锁定记录。
ladLockBatchOptimistic — 开放式批更新。用于与立即更新模式相反的批更新模式。

打开 Recordset 前设置 LockType 属性可指定打开时提供者应该使用的锁定类型。读取该属性可返回在打开的 Recordset 对象上正在使用的锁定类型。Recordset 关闭时 LockType 属性为读/写,打开时该属性为只读。

在实际使用过程中应该使用适合于处理任务的最简单的游标类型和记录锁定方式。例如:

仅打开一个静态的记录集并输出:
Rs.Open sql,Conn,0,1 ‘ adOpenForwardOnly, adLockReadOnly
打开的记录集中有text类型的字段:
Rs.Open sql,Conn,1,1 ‘adOpenKeyset, adLockReadOnly

6.4 SQL字符串过滤

所有的字符串输入框在向数据库提交查询、插入、删除或修改一条记录时必须用字符串过滤函数检查,即:
字符型:复写提交内容中的“’”、“’’”等(使用公共函数的CheckInputString()。),并检查字符串的长度是否超长。
数值型:使用IsNumeric()判断输入是否为数字。
整 型:使用Int(), Fix(),Round() 截取其整数值。
日期型:使用isDate()函数判断是否为正确的日期输入。

6.5 SQL事务执行

对数据库操作的事务一般应当使用SQL的存储过程执行。对于需要在ASP页面中执行的数据库操作,所有插入、删除、修改数据库不得使用RecordSet对象,必须使用Connect对象用SQL语句执行,RecordSet只在执行查询时使用。所有检索数据库的操作禁止使用“SELECT * FROM …”,而要使用“SELECT 字段一, 字段二, 字段三, … FROM…”。

6.6 ADO对象的关闭

所有连接数据库页面中,Connect和Recordset等ADO对象必须在用完后立即关闭(Close),然后将其对象释放(Set ***=nothing)。

五、ASP程序
5.1 变量声明
在所有用到变量的ASP页面中必须在程序说明的下一行写上<% OPTION EXPLICIT %>。因为没申明的局部变量和全局变量一样慢(比定义过的局部变量要慢一倍)。被包含的公共文件例外。

5.2 程序说明

每一个程序文件的开头必须说明文件的作用或功能、程序的入口参数、参数说明、作者、编写日期(包括生成日期、最后修改日期)。格式如下:

<%
'**
‘Comment: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
‘Input: (must) logon_id-User Name; logon_pd-User Password
‘ (plus)
‘Editor: xxxxx 2000-11
‘Modify: xxxxx 2000-12
‘**
%>

5.3 最小化上下文切换

出于服务器处理脚本性能的考虑,建议应尽量使HTML和脚本的上下文切换最小化。在可能的情况下,应在一页内使用少数大块脚本代替多个分散的片段。例如:
<% IF a > 1 THEN %>
<A HREF=”1.htm”> 第一 </A>
<% ELSE %>
<A HREF=”2.htm”> 第二 </A>
<% END IF %>
最好写成如下格式:
<%
IF a > 1 THEN
Response.Write “<A HREF=””1.htm””> 第一 </A>”
ELSE
Response.Write “<A HREF=””2.htm””> 第二 </A>”
END IF
%>

5.4 分隔脚本行以增加可读性

脚本行应该被一对定界符(“<%”、“%>”)分割为代码块,而不是在每一行上书写定界符。下面代码:
<% strEmail = Session("Email") %>
<% strFirstName=Request ("FirstName") %>
<% strLastName=Request("LastName") %>
应写成如下格式:
<%
strEmail = Session("Email")
strFirstName=Request ("FirstName")
strLastName=Request("lastName")
%>
对于单独的脚本行,在相同行上作为脚本保持定界符。例如:
<% strEmail=Session("Email") %>
如果脚本行由一个等号和一个变量组成,应将等号作为定界符的一部分。例如:
<% = strSubscrlName %>

5.5 禁止使用Session

由于SESSION 对负载均衡有影响,因此SESSION 将不再使用,而统一使用COOKIE来维护用户状态。

5.6 对于运行时间长的页面,使用Response.Flush方法

每个写操作都会产生很大的系统开销(在 IIS 中以及在通过网络发送的数据量方面),因此写操作越少越好。由于其启动慢且使用 Nagling 算法(用来减轻网络塞车情况),TCP/IP 在发送一些大的数据块时比必须发送许多小的数据块时的效率高得多。
对于运行时间长的页面,必须利用 Response.Flush 方法。这种方法将 ASP 转换的所有 HTML 送到浏览器。例如,在转换 1,000 行的表的前 100 行之后,ASP 可以调用 Response.Flush,强制将转换的结果送到浏览器,这样可使用户在其余的行准备好之前看到头 100 行。这种技术可以将响应缓冲与浏览器逐渐显示数据完美地结合在一起。而且,还能解决当产生非常大的页面时,将占用许多服务器内存的问题。
经验表明,不要每次重复执行紧密循环时都调用它,如显示表的许多行时 - 每隔二十或五十行调用一次可能比较合适。

5.7 最好迟一点获得资源,早一点释放资源

用于 COM 对象以及文件句柄和其它资源。在对象使用完毕,应及时将 VBScript 变量设置为 Nothing(在将记录集或连接设置为 = Nothing 之前,不要忘记调用 Close())。

5.8 尽可能使用 Server.Transfer 代替 Response.Redirect

Response.Redirect 让浏览器请求另一个页面。此函数常用来将用户重定向到一个登录或错误页面。因为重定向强制请求新页面,结果是浏览器必须到 Web 服务器往返两次,且 Web 服务器必须多处理一个请求。IIS 5.0 引入了一个新的方法 Server.Transfer,它将执行转移到同一台服务器上的另一个 ASP 页,并且将原页面的Request集等全部转移到新页面。这样就避免多余的浏览器-Web-服务器的往返,从而改善了总体系统性能以及缩短了用户的响应时间。
检查“重定向”中的“新的方向”,如果只是想引用一个外部的文件作为过程,然后将控制权再转回本页面,则可以使用Server.Execute。

5.9 包含文件禁止使用 .inc 为扩展名

为了防止放置在包含文件中的敏感信息被意外下载,禁止使用 .inc 为包含文件的扩展名,而使用 .asp 为扩展名,并且放置在专用的目录下