在Ajax编程时,经常需要从服务端获取数据。通过情况下,我们是直接把要传输的数据放在response正文中,再用responseText或者responseXML来得到内容。最近偶然发现,有时候也可以把数据放在header里,而且一些情况下这样做更有优势。

header是服务器以HTTP协议传送HTML资料到浏览器前所送出的字符串,在php中我们可以这么发送自定义header:

header("author:Jerry Qu");

然后在客户端,正常的创建一个Ajax请求,所不同的地方是callback中获取数据改成:

var a = new Ajax();
a.get("test.php",function(){
    
alert(a.req.getResponseHeader("author"));
});

这样就能取到author的值了。 Read the rest of this entry »

前几天发现一个WP插件:WordPress Plugin Live Blogroll,能在鼠标悬停博客友情链接上方时显示一个浮动层,来展示好友的最新文章。这么好玩的插件,怎能放过?我马上下载安装,发现还是有问题:一是样子不够帅;再者部分国内的RSS不能正常读取。于是我就产生了自己动手写一个类似插件的念头。

第一步要从链接地址中自动获取RSS地址,幸好现在大多数的博客都遵循一个统一的标准来标识RSS入口。如:

<link rel="alternate" type="application/rss+xml" title="JerryQu的小站 RSS Feed" href="http://feed.qgy18.com" />

只需要查找type=”application/rss+xml”的link标记的href属性就可以了。在php中用preg_match_all方法很容易就可以匹配出来。

然后,就可以用file_get_contents取到xml,之后用simplexml对象来解析。值得注意的是,一定要把取回的xml缓存起来,就现在的网络情况来看,实时取是不太现实的。我是把xml直接生成文件来缓存的,根据文件的最后修改时间判断是否过期。前端用JS来异步获取数据,生成浮动层,浮动层的外观是仿照MSN联系人Tip布局的,加了一个小箭头来指示当前显示的是哪条链接。

具体效果可以在本页面右侧链接处查看。现在只是实现了功能,插件的配置页还没有完成。

下载地址:http://www.qgy18.com/g/?id=2 (累计下载:次)

写完PHP版的QGYWEBIM也有一个多月了。这期间没测试出什么大毛病,加上最近不少人问我要PHP版的代码,就整理了一下提供下载了。相比之前的ASP版本,有几处小变动,在这里简单说明下:

1.支持了匿名用户。其实这个小功能是当初为了方便那些想要帮忙测试而又不想注册帐号的同学加上的。没有好好的设计,没太多实用性,就没有提供一个管理匿名用户的入口。如果你确实想提供匿名用户登录功能的话,可以参考这个帖子

2.改进了查找好友的方式。之前很多人跟我反映查找好友太不方便了,确实只能通过email地址来添加好友很不友好,尽管MSN一直如此。现在好了,我在这个版本中把查找好友的功能稍微改进了下,除了可以精确查找,还可以像QQ一样根据一些条件模糊匹配。ASP版的我也改了,只需要替换两个文件就可以了。

3.合并了一些图片。众所周知,将一些小图片合成一张大图可以显著的减少连接数,提高效率,这也就是人们常说的css sprites技术。但是为什么之前的版本中那么多的小图没有合并呢?那是因为我太懒了,合成一张大图片还要算像素太麻烦,哈哈。不过呢,我最近发现了一个很好的在线工具,它可以自动帮你把小图合并,并帮你算好像素,于是我就象征性的把其中一些小图片合并了一下,免得被人鄙视。。。

下载地址[已修复]:http://www.qgy18.com/g/?id=1 (累计下载:次)

一些相关链接:

QGYWEBIM运行截图:http://www.qgy18.com/ablum/?d=5176709877654128385

PHP+MySQL版测试地址:http://www.qgy18.com/lab/webim/

ASP+Access版测试地址:http://old.qgy18.com/webim/

说明文档:http://old.qgy18.com/webim/readme.html

Maxthon,一个大家熟得不能再熟的软件。我某位同事甚至这样的赞许它:“对我来说,Maxthon就是浏览器,浏览器就是Maxthon”。我这里不想讨论Maxthon是好是坏,只是如实的记录工作中由Maxthon带来的一些问题。我的Maxthon是官方的2.1.4,采用默认配置。由于Maxthon是一个IE Shell,我在测试中用系统自带的IE作为参考。

一、Maxthon会错误的处理某些JS事件。试着在IE地址栏中输入下列代码:

javascript:window.onbeforeunload = function(){return "你真的要关闭?"};void(0);

然后关闭浏览器当前Tab(IE7、IE8),或当前窗口(IE6),你会发现系统会给出“确实要离开页面…”之内的提示,选择“确定”才会执行关闭。但Maxthon不会这么做,弹出关闭提示时,当前tab/窗口已经关闭,无论选什么都无济于事。另外一个问题是Maxthon里鼠标右键点击,得到的返回键值不对。在地址栏输入以下代码:

javascript:document.onmousedown = function(){alert(event.button)};void(0);

在IE里右键单击返回的是2,而Maxthon返回0。这个就很让人费解了,都是IE内核,不应该有不同呐。
Read the rest of this entry »

我在5月份的一篇文章里列举了一些本地存储解决方案,包括常见的Cookie、UserData和不是那么常见的globalStorage、Database Storage。文章最后提到了另外两种解决方案:Google Gear和Flash,当时因为觉得用不上就没仔细研究。但实际应用中,那篇文章列出的方案还是不能满足项目的需求。这篇文章就讲一下如何使用Flash来实现本地存储,以及该方案使用的场合。

拿IE6来说,如果要在本地大量存放数据,Cookie因为存放内容太少、浪费用户带宽首先就应该被淘汰掉。UserData在大多数情况下能满足需求,但是它也有一个致命的弱点:只能读取同目录存储,也就是a目录下一个文件不能读取b目录下两一个文件存放的数据。MSDN说明如下:

Security Alert For security reasons, a UserData store is available only in the same directory and with the same protocol used to persist the store. 全文>>

也就是说如果项目中要跨文件夹操作本地存储,UserData也必须被淘汰了。IE不支持Database Storage,IE8才增加了对globalStorage的支持,这个时候Flash就派上用场了。 Read the rest of this entry »

最近在Dron的UCRen网站看到一种很帅的JS写法,记录一下。

UCRen是下面这样引入widget的(摘自这个页面):

<script type="text/javascript" src="../../ucren-engine/cache-boot.js?skin=qq">
  import webui.FileInput;
  import renderfactory.FormRenderer;
</script>

第一眼看到这段代码,我还在想这样写JS语法分析器不报错才怪,难道是让window.onerror返回true干掉了浏览器的错误提示?这样也太不和谐了吧!今天仔细看了看才明白了,这个script标签是有src属性的,这样写标签里的内容会被忽略掉,不会执行也不会报错。在src链入的cache-boot.js里可以用:

var scripts = document.getElementsByTagName("script");
var code = scripts[scripts.length-1].innerHTML;

来得到那些神奇的代码,然后用正则解析成正常的script标签就OK了。原理不复杂,不过很有用。可以用它写出一些很有趣的代码来。

上次一位网友在我blog留言问到如何修正Ajax后退失效,这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。

首先我们要清楚后退按钮会失效的原因:使用Ajax时,页面通过XMLHttpRequest来更新内容,并没有Redirect,所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因,其中细节可以参考这两篇文章《Ajax: 99% Bad》、《AJAX的七宗罪》。这个问题其实跟Ajax无关,不过Ajax的出现使得一个页面实现无刷新更新更容易,这个时候人们开始意识到,一个页面发生巨大改变而不能后退是一件很痛苦的事情。

要解决这个问题,就要控制浏览器的history,在页面发生改变时往浏览器历史里插入一条记录。但是出于安全的目的,JS是不能直接操作history的。我们必须采用其他方法:IE中,在页面中插入一个隐藏的iframe,通过改变iframe的location或者DOM,都可以在主窗口的history中产生新记录,详细研究可以参考这篇文章;在其他浏览器(Firefox、Opera、Safari)中没有这么复杂,只需改变url就可以产生一条新的history记录,当然url不能乱改,要不页面就跳转走了,通常我们改变的是location.hash,也就是url“#”以后的部分。下面是具体实现:
Read the rest of this entry »

以前在测试自己写的webim时发现firefox有一个很人性化的特性:在页面上跟别人聊天的时候如果不小心点到了本页打开的链接,只要点一下Firefox的后退按钮,就会退后到之前的页面,可以接着聊。也就是说在firefox中点击后退,原来页面的状态会还原,包括JS改变的DOM结构也会保持。

我们用下面的代码来测试一些常见的浏览器是怎么处理后退的。测试的浏览器有IE8beta2、Firefox3.0.1、Flock1.2.4(Firefox2.0.0.16内核)、Safari3.1(window版)、Opera9.60。

<a href="http://www.baidu.com">百度</a>
<div id="a1"></div>
<script type="text/javascript">
  window.onload = function(){
    alert("load");
    var i = 1;
    setInterval(function(){
      document.getElementById("a1").innerHTML = i++;
    },500);
  };
</script>

Read the rest of this entry »

前端开发中,经常需要动态的添加、移除或者获取元素的Attribute。也就是说经常会用到setAttribute、removeAttribute和getAttribute。今天要讨论的是开发中遇到的几处IE与Firefox对Attribute操作的差异。

属性名大小写

在Firefox中,属性没有小写的概念,就算属性名全用大写,Firefox也会解析成小写,用Firebug看就能看到。所以下面的代码在Firefox与IE中运行结果会不一样。

<div altStr="sss"></div>
<script type="text/javascript">
 var div = document.getElementsByTagName("div")[0];
 div.removeAttribute("altstr");
 alert(div.getAttribute("altstr"));//IE中返回sss,FF中返回null
</script>

不过在IE中,removeAttribute有第二个参数,设置为true表示不忽略大小写,为false时忽略大小写,默认值是true;Firefox中因为解析时就不存在大写属性了,所以就没有第二个参数。也就是说IE中removeAttribute(“test”,false)等同于Firefox中的removeAttribute(“test”),IE中removeAttribute(“test”,true)在Firefox中无法实现。 Read the rest of this entry »

我打算写一个系列文章,介绍webim的方方面面,今天开始第一篇。

我之前发布了一个webim,那个im设计了前端UI、交互,后端程序和通讯只是随便写了一下。作为一个交互很多的web应用,良好的后端设计可以减少数据库访问、减轻服务器负载;良好的通讯模式更是可以较少服务器连接数、节省流量。这篇文章主要讲web即时通讯中常用的技术。

HTTP是无连接的,HTTP通讯过程基本就是:客户端发送请求给服务器,服务器接收请求给出响应信息,客户端接收响应信息显示在用户的显示器上,客户端断开连接。由此可知,要实现即时聊天中的”即时”,我们有两个办法:服务器抓住连接不断开和客户端不断的向服务器发起请求实现伪即时。当然用Flash XMLSocket可以实现真正的即时通讯,但这样已经不是使用HTTP协议了,HTTP天生的优势(无需另外开端口、自动穿越防火墙)也就无法体现。 Read the rest of this entry »

关于我

JerryQu,当前从事前端开发,@中国北京
这里是我随便记录东西的地方~
需要找我,我的联系方式在这里 »
查找QGYWebim相关信息,请点这里 »

共享