意想不到的循环调用

前端开发  |  7年前

前几天公司有一个页面在IE下一打开就弹出这样的错误:

Stack overflow at line: 0

一般来说,这是Javascript出现循环调用时报的错。由于页面上的代码比较多,无法一下子判断出是哪里的问题,我只好一段一段地删。然而,即使我把所有的<script>标签都删了,这个错误仍然存在。我又怀疑这是嵌入的外部文件导致的问题,于是又把所有的<iframe>标签给删了,但问题依旧。

难道HTML也会导致循环调用吗?其实我算漏了一个地方,就是HTML元素的事件,可以通过标签的“onEventName”属性指定,比如“onclick”、“onmouseover”等。这下终于让我找到了线索:页面上的一张图片设置了“onerror”事件。代码大概如下:

<img src="a.jpg" onerror="this.src='b.jpg'" />

onerror事件用得比较少,但它本身并不会造成什么问题。然而,这里的“a.jpg”和“b.jpg”都是不可访问的。访问“a.jpg”的时候出错触发了onerror事件,把图片的地址设为“b.jpg”,问题就在于“b.jpg”也不可访问,又触发了onerror事件,再次设为“b.jpg”,这自然也是不可访问,继续触发onerror事件,如此往复。

608次阅读,2条评论

回忆软盘和软驱

工作生活  |  8年前

今天在cnBeta上看到一则消息说Sony软驱停产了,想起以往用软驱和软盘的日子,真是感慨万分。

曾几何时,3.5寸软盘是最常用的移动存储介质。虽然它的容量只有1.44M,但是在那个年代,硬盘也就几G,作为移动存储介质的软盘,容量也不算小了。它的价格也不高,即使文件比较多,多买几张就可以装下。我上初中的时候家里还不能上网,偶尔到亲戚家下载资料,也就靠着几张软盘把资料拷回家。那时用的是56K Modem的拨号上网,实际速度也就5kb/s左右,1个小时也下载不了多少东西,所以用软盘可以装得完。此外,一些软件也使用软盘作为存储介质,比如高中时候买的一套瑞星2003版,是必须插入附带的软盘才能安装的。

随着硬件技术的进步,软盘容量小、传输慢的缺点已经越来越突出。到高中的时候,我基本上没有用软盘了,取而代之的是光盘(CDR、CDRW)和换下来的一个3.2G的台式机硬盘(当作移动硬盘用,接线的时候要拆机箱)。后来,大容量硬盘、光盘、U盘的面世终于把软盘赶上了绝路。从那时起,电脑城的装机配件单里面就没有软驱这一项了。

上大学以后,我终于把所有软盘丢了,新装的电脑也没有配软驱。瑞星也早已升级,不需要软盘了。从此,软驱和软盘彻底退出了我的生活。

382次阅读,3条评论

使用JScript遍历Request表单参数集合

其他开发  |  8年前

JScript下有一个Enumerator对象可以遍历集合。根据它的文档写了以下程序,可以遍历整个Request.QueryString集合:

var params = new Enumerator(Request.QueryString);
while (!params.atEnd()) {
  Response.Write(params.item() + ":" + Request.QueryString(params.item()) + "<br />");
  params.moveNext();
}

美中不足的是,Request对象本身不是集合,所以不能对Request对象进行遍历,下面这行代码会报错:

var params = new Enumerator(Request);
722次阅读,0条评论

混乱的Javascript相关名称

前端开发  |  8年前

LiveScript

LiveScript是JavaScript语言的前身。自从Sun公司推出著名的Java语言之后,Netscape公司引进了Sun公司有关Java的程序概念,将自己原有的LiveScript重新进行设计,并改名为JavaScript。

JavaScript

JavaScript是一种广泛用于前端开发的脚本语言,前身是LiveScript。它已经被Netscape公司提交给ECMA制定为标准,称之为ECMAScript,标准编号ECMA-262。目前最新版为ECMA-262 3rd Edition。

ECMAScript

ECMAScript是由Ecma国际(前身为欧洲计算机制造商协会)通过ECMA-262标准化的脚本程序设计语言核心。所谓核心,意思是它并不作为一种独立的语言出现,而是为不同种类的宿主环境提供脚本语言的核心功能。Javascript、JScript、ActionScript等都基于ECMAScript,都是ECMAScript的扩展。

518次阅读,0条评论

使用JavaScriptSerializer进行JSON序列化

其他开发  |  8年前

JSON是Javascript中常用的数据格式,然而,在.NET 2.0中没有内置序列化JSON的类,原因估计是当时Ajax尚未兴起。后来就有人写了一个Json.NET类库。.NET 3.5新增了一个把对象序列化为JSON字符串的类JavaScriptSerializer。这个类位于System.Web.Script.Serialization名字空间中(非Web项目需要添加System.Web.Extensions.dll引用),其使用方法也是非常简单的:

// 分类
public class Category
{
  public int CategoryId { get; set; } // 分类编号
  public string CategoryName { get; set; } // 分类名
}

Category testCategory = new Category()
{
  CategoryId = 1,
  CategoryName = "Test"
};

JavaScriptSerializer serializer = new JavaScriptSerializer();
Console.Write(serializer.Serialize(testCategory)); // 调用Serialize方法进行序列化
11698次阅读,0条评论

Windows 7使用报告

工作生活  |  8年前

7月中旬以来就有不少Windows 7已经RTM的消息,但是直到月底才确定了16385是最后RTM版本。后来就有一个号称是联想的OEM版本连盘带key泄露。我到远景论坛进一步确认此事,发现部分网友已经安装了这个版本,并称只要是联想的品牌机而且BIOS中的SLIC是2.1版本就可以自动激活。

这个消息估计刺激了不少用联想PC的用户,包括我。但是原生SLIC 2.1版本的机器还不多,于是各论坛都在盛传刷SLIC的方法。我按照其中一个方法刷了自己的F41笔记本,并成功安装激活Windows 7。用了差不多一个星期了,下面分享一下安装使用的感受。

安装

其实试用RC版的时候就有这个感受,Windows 7的安装速度还是挺快的,甚至比XP和2003都快。安装的时候要注意,系统分区一定要用Windows 7的NTFS格式(最好在选择系统盘的时候格式化一次),否则是不允许安装的,其他分区则无大碍。如果是普通用户,系统分区15G左右就够了;如果是像我这样做开发的,最好预留25G。

装好以后开启了IIS的相关服务,并关闭了游戏和侧边栏。

516次阅读,1条评论

有趣的招聘广告

工作生活  |  8年前

刚刚在cnbeta上看到一则消息,内容是趣味招聘广告,据说是微软英国的设计图。

微软英国招聘

大概意思是“诚邀可解决此问题者,请立即拨打以下号码:”,至于号码是什么就要自己算了。这是很简单的运算,通过一段C#程序可以得出结果:

int x = 24, y = 30;
Console.Write("01." + (y * y - x).ToString() + "." + ((y * y - 10 * 10) * 10).ToString());

结果是"01.876.8000"。

1687次阅读,3条评论

把具有数字属性名的对象转换为数组

前端开发  |  8年前

虽然不太常用,但我们的确可以给对象添加以数字为属性名的属性:

var obj = {};
obj[0] = 1;
obj[1] = 2;

这个对象并不是数组类型,那有没有办法把它转换为数组类型呢?jQuery代码中采用了Array.prototype.slice把这种对象转换为数组,但我试了好几遍,就是不行:

var obj = {};
obj[0] = 1;
obj[1] = 2;
alert(Array.prototype.slice.call(obj));
598次阅读,0条评论

重置SQLite中的自动编号列

其他开发  |  8年前

目前流行的数据库都提供了自动编号类型,SQLite也不例外。当数据库中包含自动编号的字段时,SQLite会自动建立一个名为 sqlite_sequence 的表。这个表包含两个字段:nameseq 。name字段记录了自动编号字段所在的表,seq字段记录了当前用到的序号(下一条记录的编号就是当前序号加1)。

在开发过程中,我们经常要把表重置。也就是说把表中的记录全部清空,并把自动编号归0。在SQLite中,只需要修改 sqlite_sequence 表就可以了:

UPDATE sqlite_sequence SET seq = 0 WHERE name = 'TableName'

也可以直接把该记录删掉:

DELETE FROM sqlite_sequence WHERE name = 'TableName'

要是想重置所有表,那直接把 sqlite_sequence 清空就可以了:

DELETE FROM sqlite_sequence
3409次阅读,0条评论

SQLite在字符串比较中的大小写问题

其他开发  |  8年前

大部分数据库在进行字符串比较的时候,对大小写是不敏感的。但是,最近使用SQLite的时候,却发现它的情况恰好相反。

假设表User的结构和值如下:

 UserName
1User1

执行下面的SQL语句:

SELECT * FROM [User] WHERE UserName = 'user1'

结果是没有找到任何记录。明显地,SQLite在进行字符串比较的时候,默认对大小写是敏感的。这会对应用程序造成不良的影响。比如,用户在输入用户名的时候必须严格按照大小写输入,这是一种很不好的用户体验;用户表中可能同时存在 user 和 USER 两个用户,容易造成混淆。

由于SQLite是近年来才兴起的数据库,中文资料少得很。Google了一些英文资料,终于找到了三种解决方案:

3071次阅读,0条评论