JavaScript 中为 Date 类实现 DateAdd 方法

JavaScript 中的并没有提供像 VBScript 里的 DateAdd 方法用于日期的操作,像加一年,减一个月什么的,这在服务端经常用到,比如设置 Cookie 的到期时间为现在时间的后一年,那么就需要使用这个方法了。

虽然 JavaScript 中没有 DateAdd 方法,但是 Date 类却有设置年月日时分秒的方法,比如 setFullYear、setMonth 之类的,而且,这些个方法的参数是可以为负的,在设置之后, Date 类会自行进行调整,每个月是30天还是31天,年份是不是闰年都不用我们来管了,只管设置值就是。

有了这个特性之后,我们就可以很方便的来为 Date 类添加 add 方法了。之所以不添加一个 DateAdd 方法而是给 Date 类添加一个 add 方法是因为我觉得那样更加方便,当然你也可以将 Date 类的 add 方法转换成为一个全局函数 DateAdd。

为了对每一个 Date 类的实例都有效,这里用到了 prototype 对象。

在 VBScript 里的 DateAdd 方法是用一个字符串来控制所加的量是年还是月还是其他的,所以在这里我也模仿 VBScript 里的 DateAdd 方法,使用一个字符串来控制所加量对应的部分,比如 y …

阅读全文 »

[ASP] 解决 JScript 中使用日期类型数据时出现类型错误的问题

在服务端JScript中,有些时候需要使用日期类型的数据,比如说设置一个cookie的到期时间,更新数据库中的日期字段等。但是按照平常的方法来用js里的date类型数据时,运行时就会发生错误。

例如以下代码:

  • <%@LANGUAGE="JScript" CODEPAGE="65001"%>
  • <script language="JScript" runat="server">
  • Response.Cookies("xujiwei")("name") = "xujiwei";
  • Response.Cookies("xujiwei")("gender") = "male";
  • var expiredDate = new Date(2008, 11, 31);
  • Response.Cookies("xujiwei").Expires = expiredDate;
  • </script>

在浏览器中打开之后,就会出现以下错误:

Microsoft JScript 运行时错误 错误 '800a000d'

类型不匹配

/temp/test.asp,行 6

这就意味着,我们按照类似在VBScript里的使用日期类型数据的方法在JScript不再行得通,但是我们总是需要在服务端中使用日期类型数据的,如果操作数据库是采用参数化Command的方式的话,那么需要使用日期类型数据的地方会更多,总不能因为不能使用常规方法来添加一个日期参数而把它放在SQL语句里吧。

幸好,JScript的设计者们考虑到了这一点。JScript在服务端使用时,往往是做为ASP的另一种脚本语言,而JScript则是微软在JavaScript上发展而来的微软自己的东西,考虑到这一点也是应该的。

在JScript中,解决这一问题的关键就是,Date类型的对象提供了一个函数getVarDate,它在JScript语言参考的说明如下:

当与 COM 对象、ActiveX® 对象或其他以 VT_DATE 格式接受和返回日期值的对象(例如 Visual Basic 



阅读全文 »

Windows 下配置 CVS 服务器

在进行团队项目开发的过程当中,源代码版本控制是不可缺少的部分,我目前用过的代码版本控制工具就两个,Visual Source Safe和CVS,呃,准确来说,CVS是昨天才开始用的。

本来,我是一直用着VSS的,比较方便,直接集成在VSS里面,但是目前在写的XBS是ASP的,Visual Studio里没有ASP的项目,不像PHP可以有个vs.php,所以比较麻烦,一直用EditPlus来写XBS。前两天因为一个项目用PHP的,又想到了Eclipse有个PDT的,就去下了个已经配置好的开发PHP的Eclipse IDE,然后想要弄个代码版本控制工具,就想到了CVS这个开源界鼎鼎有名的东西,立马上网去搜,找到了for Windows的版本:cvsnt。

cvsnt是cvs Windows版本的服务端程序,提供基于 TCP/IP 协议的 CVS 服务,可以在http://www.cvsnt.org/下载到。找到了服务器程序后,找了几天篇教程,就开始配置CVS服务器。

准备工作

从http://www.cvsnt.org/下载cvsnt,我下载的版本是2.5.04。

安装cvsnt

直接双击运行cvsnt安装文件,安装过程中可以选择以经典、自定义和完全三种方式安装,在自定义方式中可以选择安装路径。安装完成后,在控制面板里出现一个CVSNT Server的项目,图标是一条鱼~~

配置cvsnt

安装完成cvsnt后,就可以从控制面板中那条鱼来配置cvsnt了。首先,你要新建一个目录用来存放cvs仓库,我用的是G:\CVSROOT。这里需要先了解两个概念:cvs仓库和模块。我是这样理解的,cvs仓库相当于VS里一个解决方案,它可以包含多个项目,即模块。

打开cvsnt的控制面板后,可以看到7个选项卡,分别是:Server Information,用于查看服务器信息及一些简单的统计信息;Respository configuration,配置CVS仓库,包括添加、删除等;Server Setting,配置服务器运行的一些参数,诸如端口、加密、压缩等选项;Capatiblity Options,有关兼容性的选项,在这里主要配置一个兼容非cvsnt客户端的版本响应为cvs 1.11.2;Plugins,插件配置,安装完成可以不用管的~;Advanced,安装完成后也不用管了;About,在这里可以管理cvsnt服务的状态,停止或启动cvsnt和cvsnt lock服务。

其实简单来说,custom换默认设置安装完成后,要设置的东西只有两个:cvs仓库和服务器设置。

服务器设置:设置Run as为系统管理员帐号Administrator,或者新建一个本地用户,专门用于cvs。使用一个新建的本地帐户的好处是可以使用NTFS的权限控制来保证服务器的安全。

CVS仓库设置:进入Respository configuration选项卡,点击Add,出现添加CVS仓库的对话框,Type选择Standard即可,然后在Location里输入之前新建的用于存放CVS仓库的文件夹,我用的是G:\CVSROOT,在Name里会自动转换成一个可以用的CVS仓库的别名,比如我用的是“/CVSROOT”,其他的都默认,确定后cvsnt会询问你所添加的CVS仓库目录没有初始化,是否进行初始化,点“是”就行了,cvsnt会自动初始化指定的目录,初始化完成之后,可以在里面看到一个CVSROOT的文件夹。

认证设置:配置完CVS仓库后,为了使CVS能使用帐号进行访问而不是使用windows用户,需要修改cvsnt的认证方式,在CVS仓库目录的CVSROOT目录里找到config文件,先把它的只读属性去掉,然后使用文本编辑器打开,将第一行的#SystemAuth=yes改成#SystemAuth=no。

用户设置:在CVSROOT目录里,新建一个passwd文件,用文本编辑器打开,添加两行内容:

cvsroot:

xujiwei:

可以把“xujiwei”改成你要用的用户名。

修改密码:添加了用户之后,最好把密码修改掉。修改密码需要在cmd中进行,首先打开一个cmd,设置一下cvsroot环境变量:

set cvsroot=:pserver:[email protected]/cvsroot

注意,这里的xujiwei是之前添加的用户名,/cvsroot是之前添加的CVS仓库的别名,如果你的设置不同,请把它们替换成自己的值,以后不再说明。

接着登录CVS服务器,因为添加用户时没有设置密码,因此可以不输入密码直接回车登录:

cvs login

修改密码:…

阅读全文 »

解决 ADODB.Stream 0x800A0C93 错误

ADODB.Stream在ASP编程中往往用于无组件上传,并且可以指定文件编码,可以应对各种不同的需要。但是在使用ADODB.Stream过程中,往往会发生这样那样的错误,昨天就碰到了一个0x800A0C93错误,在网上找了半天也没找到解决方法,找到的都是些什么权限的问题,但是在我使用的时候,权限配置并没有问题,因此只好自己琢磨了。

如果要再现这个错误,可以使用以下代码:

  • <script language="jscript" runat="server">
  • var obj = Server.CreateObject("ADODB.Stream");
  • obj.Mode =1;
  • obj.Type = 2;
  • obj.Open();
  • obj.LoadFromFile(Server.MapPath("test.asp"));
  • Response.Write(obj.Read());
  • obj.Close();
  • </script>

因为在使用ADODB.Stream时,我是想用它来读取文件,所以使用了Mode 1 - Read,然后使用LoadFromFile方法载入文件,但就是这里,出现问题了,运行到LoadFromFile的时候,出现错误,提示“应用程序请求的操作不允许出现在该上下文中 ”,弄了半天也没解决。

去网上找,解决方法大都一样,权限设置不对什么的,解决不了我的问题,只好继续自己琢磨。

又折腾了一会之后,想到,会不会是Mode的问题,因为之前这段代码是用得好好的,但是在放到我写的一个类的Read方法中之后,就把Mode改成1 - Read了,又想到,LoadFromFile方法应该是把所指定的文件内容写入到了ADODB.Stream对象的缓冲区当中,所以需要写权限,当下测试:

  • <script language="jscript" runat="server">
  • var obj = Server.CreateObject("ADODB.Stream");
  • obj.Mode = 3;
  • obj.Type = 2;
  • obj.Open();


阅读全文 »

在ASP里面创建GUID

GUID在许多时候做为唯一标识符都很方便,但是在ASP里并没有现成的函数来创建GUID,其实可以使用Scriptlet的类型库来创建一个GUID,代码如下:

JScript

  • function GenerateGuid() {
  • var TypeLib = new ActiveXObject("Scriptlet.TypeLib");
  • return (TypeLib.Guid);
  • }

VBScript

  • Function GenerateGuid()
  • Dim TypeLib
  • Set TypeLib = Server.CreateObject("Scriptlet.TypeLib")
  • GenerateGuid = TypeLib.Guid
  • End Function

如果要在客户端使用的话,VBScript的代码需要稍做修改,即把:

Set TypeLib = Server.CreateObject("Scriptlet.TypeLib")

修改为:

Set TypeLib = CreateObject("Scriptlet.TypeLib")

但是在客户端使用ActiveX的时候,IE默认的安全设置会提示是否允许使用ActiveX,所以并不推荐使用。

希望对你有所帮助。

[AJAX] ASP中使用GB2312编码时处理乱码问题

在AJAX开发中,编码问题往往是令开发者比较头痛的,特别是在编码不是UTF-8的情况下。虽然这篇文章是讲的怎么处理乱码问题的,但是我还是推荐在做AJAX开发的时候使用UTF-8编码,这样可以避免很多问题。

AJAX中,XMLHttpRequest发送数据和接收数据的时候往往都是使用UTF-8来处理数据的,也就是说,虽然程序是使用GB2312作为编码的,但是XMLHttpRequest还是以UTF-8来处理,这样就导致乱码问题了。

所以如果要解决乱码问题,可以通过指定文件编码来解决。指定文件编码后,XMLHttpRequest就会使用指定的编码来处理文件,这样,碰到GB2312编码的文件时,XMLHttpRequest还是能以GB2312编码来读取文件,这样就能避免乱码了。

要设置编码方式,可以发送ContentType头来指定。

在ASP里,要设置ContentType,可以用以下语句:

  • Response.ContentType = "text/html; charset=gb2312"

在ContentType里,charset就指定了文件编码。

一般在AJAX客户端需要处理和显示中文数据时候,最好在服务端设置文件编码,即设置ContentType。如果服务端不知道是否会返回中文数据,那么还是设置一下编码的好。

这样处理AJAX中乱码的方法并不局限于ASP,比如在PHP里也可以使用header函数来设置ContentType。其实理论上只要能在服务端设置HTTP请求的header,就能通过这样的方式来解决乱码问题。

就这样。

Windows Mobile 中启动外部应用程序

Windows Mobile下面Java一直没有比较好的模拟器,用了一段时间的JMM最新版,觉得不错,但是有些程序还是不能运行,就去下了个JBed,但是在JBed中安装程序时会搜索卡,感觉比较费时,用Resco Explorer用JBed带参数打开时,又安装不了,因为需要加额外的参数-ginstall,Resco Explorer不支持。

另外一种方法就是把 .jar 文件的关联改到JBed,不过平时主要用的JMM,不想改掉关联,所以想着写个程序,作为代理,在Resco Explorer里把 .jar 文件的路径传给这个代理,再通过这个程序带参数启动 JBed 来安装。

要做到这些,就需要在这个代理中启动外部应用程序,第一次写Windows Mobile下面的程序,不过都是微软一家人,也不是麻烦,在Google上找了资料,发现可以用 ShellExecuteEx 来启动外部应用程序,然后就开写了。

程序的主要代码就一段,功能就是接受参数,启动 JBed。

wchar_t* param;
param = (wchar_t*) LocalAlloc(LPTR, 255);
wsprintf(param, _T("-ginstall \"file:\\%s\""), lpCmdLine);
SHELLEXECUTEINFO execInfo;
ZeroMemory(&execInfo, sizeof(execInfo));
execInfo.cbSize = sizeof(execInfo);
execInfo.lpFile = _T("\\Storage Card\\J\\jbed.exe");
execInfo.lpParameters = param;
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
execInfo.lpVerb = _T("open");
ShellExecuteEx(&execInfo);



阅读全文 »

ActiveSync 和 DHCP Client

2003莫名的挂掉了,关不了机,加上2003用的时候越来越少,Vista的兼容性有些问题,就决定重新装回XP。

装完XP,按自己的喜好设置了一番,装好ActiveSync插上数据线跟手机同步,发现同步不了,郁闷。

可以说装XP的一大目的就是为了跟手机同步,原来在2003就一直同步不了,在Vista用移动设置中心倒是能同步的。

同学的电脑上用XP是能同步的,仔细想了想我的系统跟同学的有啥不同,好像也没啥,然后再试了下,注意到屏幕右下角总是有一个网络连接的图标在获取IP,同学的电脑用时却没有。再弄了会的时候突然想到了,会不会是我优化服务时把DHCP Client服务给设置为手动了的原因,导致Windows Mobile-based Device分配不到IP,然后就一直同步不了。

想到这,马上打开服务管理器,把DHCP Client服务启动了,果然,ActiveSync响了一声,箭头开始转起来。

弄了这么久,总算解决了这个问题,在想微软是不是应该在ActiveSync的帮助或者哪里说明一下ActiveSync同步是需要 DHCP Client服务的。

XSL中的运算符与变量名

昨天在写XSL模板的时候,在模板中使用了一个变量,结果在调试的时候却怎么也不行,我的变量名是$ItemCount,然后在模板中使用了这个变量 :

  • <xsl:value-of select="Tag[position() = $ItemCount-1]" />

在调试时却总是提示“无法解析到变量或参数 'ItemCount-1'的引用。变量或参数可能没有被定义,或它可能不在范围内。”,我就奇怪了,这名字明明是对的,怎么会有错呢,然后就又在变量定义的地方把变量名给复制过来,看看还是不是会出错,结果还是一样的错误。

这下郁闷了,懒得伺候了,把东西扔一边,玩去了~

今天想到这个事,再不行这个模板总是要写完的,于是又开了EditPlus,找到那一句,就在想怎么改它,突然脑子里来了一点点灵光,在减号的两边各加了一个半角空格,Firefox里打开,bingo!正确执行。

在解决了这个问题之后才想到,短划线也就是“-”在XML里是符合命令规范的,也就是说,我在写成“$ItemCount-1”的时候,XSL Parser 把“$ItemCount-1”认为是一个变量,而不会认为是一个表达式,因此,就会提示找不到变量,出错。

找到问题的原因所在,就好解决了,直接把减号给独立出来:

  • <xsl:value-of select="Tag[position() = $ItemCount - 1]" />

解决问题,继续写模板。

[ASP] 《在JScript中使用缓存技术》补遗

《在JScript中使用缓存技术》一文中,在JScript中实现了基于Application.StaticObjects的缓存技术,并且实现一个类用于缓存的操作,但在实际使用过程中仍需要注意一些问题。

在JScript的函数中,如果参数类型是number或者string,那么是按值传递的,但如果是object,那么就是按引用传递了。另外,数组在JScript中也是作为一个特殊的对象对待,因此,数组的类型也是object,同样是按引用传递的。

使用xbsCache类进行保存和获取数据操作即put和get时,不管是按值还是按引用,都没有问题,但是在使用过程中,对数据操作的效果由数据类型不同而不同。

如果数据是number或string类型的,那么在get数据时,返回值是按值的,也就是说,我们得到的数据是缓存数据的一份copy,对变量的操作并不会影响到缓存中的数据,例:

  • // code by xujiwei
  • // from www.xujiwei.cn
  • var myname="my name is xujiwei";
  • xbsCache.put("name",myname);
  • // 从缓存中获取name,值为"my name is xujiwei"
  • var myname2=xbsCache.get("name");
  • // 给myname2赋值"xujiwei"
  • myname2="xujiwei";
  • // 从缓存中获取name,值仍为"my name is xujiwei"
  • var myname3=xbsCache.get("name");

但是在数据类型为object的情况下,我们就需要注意,在从缓存中获取数据之后,我们得到的只是一个指向缓存数据的引用而已,并不是缓存数据的copy,因此,对数据的修改是直接影响到缓存的,例:

  • // code by xujiwei
  • // 


阅读全文 »