Javascript Widget入门解析

收到Erica的来信,希望知道采麦的Widget是怎么做出来的,突然想起当年我第一次写widget代码的时候,也是满世界找不到一个简明实用的教程。于是做个总结,也许更多人可以用得到。

复习一下两个js函数:

js可以动态生成网页代码,比如:

document.write(’<div id=”photo”>123</div>’);

这段代码可以让网页里显示出一个叫photo的层,里面还有数字123。

此外,js可以动态改变网页内容,比如这段代码:

document.getElementById(’photo’).innerHTML=’abc’;

就可以让这个photo层里显示abc,而不是原来的123了

别看这么一段小代码,其实这就是整个widget的核心了

技术原理:

widget有3个重要部分组成:数据、外壳、脚本。

  • 数据:就是你希望显示出来的内容,比如你要显示flickr上最近的照片,那么照片就是数据;
  • 外壳:就是容纳数据的容器,比如上述照片,你把他们包裹到一个叫photo的div里,那么这个div就是外壳。
  • 脚本:脚本的作用是生成外壳,并把数据填充到外壳里,主要就是js代码,当然也可以带一些css

所以,理论上,一个原始的widget代码应该是这样的:

<script type=”text/javascript”>//调用js脚本

document.write(’<div id=”photo”></div>’); //js脚本生成外壳photo

document.getElementById(’photo’).innerHTML=’abc’; //js脚本把数据abc填充到外壳photo

</script>

是不是很简单?是很简单,可惜太长了,于是把上面四行代码的中间两行提取出来,复制放到一个wjs.js文件里:

document.write(’<div id=”photo”></div>’); //js脚本生成外壳photo

document.getElementById(’photo’).innerHTML=’abc’; //js脚本把数据abc填充到外壳photo

这样只需要调用一下就可以使用widget了:

<script type=”text/javascript” src=”wjs.js”></script>

好了,到这里你已经学会了最简单的widget制作,快去实验一下吧。

基础进阶:

那么,如果数据不是abc怎么办呢? 很简单,把数据独立出来就可以了。我们改造一下wjs.js代码:

document.write(’<div id=”photo”></div>’);   //利用js建立photo层,生成外壳
document.write(’<script type=”text/javascript” src=”widget.js”></script>’); //js填充数据

数据就在widget.js里,我们分析一下其代码,只有一句:

document.getElementById(’photo’).innerHTML=’xxx’;

这样的话,要改变数据,只需要把widget.js里的xxx换成任何内容即可,而无需改动wjs.js

中级进阶:

如果要自动动态改变数据xxx,只需要把widget.js也做成动态的,以php为例,首先把wjs.js修改一下:

document.write(’<div id=”photo”></div>’);   //利用js建立photo层,生成外壳

document.write(’<script type=”text/javascript” src=”widget.php?user=howard></script>’); //js填充数据

注意里面的widget.js换成了widget.php,后面还跟了一串变量,这样就可以显示为howard量身定制的数据了,看看widget.php的代码:

<?php
Header( “Content-type: text/javascript”); //声明文件类型为js

$user=$_GET['user']; //读取user变量 (howard)

echo “document.getElementById(’photo’).innerHTML=’hi, my name is $user’; “;

//输出动态内容(hi, my name is howard)

?>

到这里,我们已经可以根据不同变量来自动显示不同的数据了。后面就很简单了,把widget.php任意改造,读取数据库,可以输出各种各样关于howard的数据。

实战应用:

事实上,实际应用中,wjs.js也被改造成了动态文件,比如wsj.php,这样你的用户howard只需要在其blog里插入以下代码,就可以真正实现个性数据调用:

<script type=”text/javascript” src=”http://domain.com/wjs.php?user=howard”> </script>

wjs.php的内部代码是这样的:

<?php
Header( “Content-type: text/javascript”); //声明文件类型为js

$user=$_GET['user']; //读取user变量 (howard)

echo “document.write(’<div id=”photo”></div>’);”   //利用js建立photo层,生成外壳

echo “document.write(’<script type=\”text/javascript\” src=\”widget.php?user=$user\></script>); “; //动态调用widget.php

?>

这样,widget.php收到了user变量之后,就能显示出howard的个性数据。

先写到这,大家可以先回去测试一下。真正能用的widget,代码和上面有很大区别,但是原理是相同的。

一种新型、有效、合法的DDOS攻击方法

今天下午吐司网的服务器出现了明显了受攻击病状

结果查了log之后,发现访问均来自天涯的一个帖子,那个帖子里从吐司链接了一百来张图片,最郁闷的是,这个帖子居然还上了天涯的首页

情况可想而知,apache的线程高达285个,濒临崩溃。

虽然发帖人是自己人,但这个倒是提供了一种高明的攻击方法

服务器租用、域名注册必须注意的几点

1、一定要支持远程ssh,不然备份的时候你会郁闷死

2、一定要有独立IP,不然跟你同ip的非法网站会把你一起拖下水

3、一定要支持fsockopen()函数,不然你的Email系统将会处于最原始最落后的状态

4、一定要支持mod_rewrite,原因我就不说了

5、一定不能用大陆的虚拟主机(虚拟空间),我的亲身经历,受够了

6、绝对不要注册.cn域名,.cn域名是中国人管的,只要是中国人管的东西,什么出问题那就欲哭无泪了。当年还比较出名的牛博网(bullog.cn)被关,域名被强制指向一个低俗透顶的垃圾网站,谁干的? 万网干的,为什么万网有能力这么干?因为它是.cn。参考文章:《警告——不要在国内注册和使用CN域名》

7、绝对不要用大陆的域名注册商。 即使是.com,只要你在国内注册,就有你的好看。 .com域名一夜之间改变了所有人和ip指向的事情,已经不是一次两次了,而且这种事情只有中国可以发生。

据我所知,同时满足1、2、3、4条件的服务器,国内只有独立主机才会有(租金大概5000~10000之间/年),独立主机的速度一般不错,可以考虑。

再次强调:大陆的虚拟主机千万不要用,年轻的时候几乎用遍了国内的每一个知名的虚拟主机,包括中国频道,中资源,万网。。。。。。没有一个不是垃圾。国外3000G的空间才卖60美金一年,万网200M的垃圾空间要卖5000元。国外的mysql数据库免费无限量,国内的50M数据库就要另加400元一年,无耻到极点。更不用说ssh,独立IP等了。

顺便点评一下国外比较流行的两个公司:IXWebhostingMediaTemple

IXWebhosting:免费赠送8个独立IP,可以放很多个网站(而且可以直接用IP访问),这点很牛。我用过一年时间,有两个大问题:1、不支持SSH,备份和转移非常麻烦;2、经常出现无法上传的问题,查了之后发现是“out of disk space”,明显是服务器配置错误,联系在线客服之后,10分钟左右就解决好了。但是经过连续4次同样的问题之后,我彻底失去耐心了。于是换到了大名鼎鼎的MediaTemple

MediaTemple: IT知名博客TechCrunch就是用MediaTemple,其界面UI设计堪称完美,可以说是主机界的苹果电脑。价格偏高,但功能强大,口碑甚好,可谓物有所值。提供ssh,一个独立IP,Lamp很强大,可自由切换php4和php5,数据库支持mysql和postgres,还支持crond计划任务。说说大家最关心的网速:我在国内的下载速度可以达到1.2M/s,居然远远超过国内的独立主机。不得不服。已经使用了四个月,非常满意。唯一的美中不足是,大部分软件都没有权限安装。

最后,注册域名千万别用国内的注册商,理由如下:

1、国外只需要7美金一个.com域名,换算一下也不到50元;而国内要卖100~150元

2、在国内,你花了钱注册了域名,管理权却并不真正属于你。注册商里的任何一个员工都可以轻易的把你的域名所属权搞成别人的

3、在国内,你注册了域名,如果某一天想更换注册商,可谓比登天还难,因为更换的时候需要向国内的注册商请求一个“转移密码”才能完成,而这个转移密码,他们是不愿意告诉你的

4、国外的域名解析措施更加完整方便 ,可以指定多个子域名,自由设置A记录、CNAME、MX记录等,国内却限制多多

国外的域名注册商建议用godaddy.com,最保险。国外也有很多垃圾注册商 ,小心为妙。

Firefox和IE的CSS兼容性问题漫谈

先从设置最小高度:min-height说起吧

对于某些内容可变的层(比如用户评论),我们希望它有个最小的高度(比如30px),这样的话,即使内容只有一行字,也不会太难看;同时又希望在内容比较多的时候,层的高度能自动撑开,也就是要求height: auto。这时候就可以设置css的min-height属性。min-height在Firefox里有效,但IE无法识别。可以使用下面这个解决方案:

.div_class{min-height:30px;height:auto !important;height:30px;}

第一行设置 min-height:30px;对Firefox有效;第二行height:auto !important;也对Firefox有效,后面紧跟的“!important”是Firefox专用的一个标记,带有这个标记的设置具有最高优先级,之后的设置都无效。所以第三行的height:30px对Firefox无效了;同时,由于IE无法识别min-height和“! important”,所以只有第三行有效,由于IE默认就是高度自适应的,所以即使设置了30px的高度,只要内容很多,也会自动撑开,不需要设置 height:auto。最后,上述代码产生如下效果:

对于Firefox,等同于:

.div_class{min-height:30px;height:auto;}

对于IE,等同于:

.div_class{height:30px;}

“!important” 是个非常好用的东西,如果你写过几个月的跨浏览器的CSS代码,就很容易被Firefox和IE之间的差别而感到恼火。比如padding属性就是一个例子。

假设这样一个层:

.div_name {width:100px;padding:10px;}

在IE里面,层的宽度是100px,四周的余空为10px;但是对于Firefox,层的宽度变成了100px+10px+10px=120px,对于宽度敏感的设计来说,整个就混乱了。怎么办呢?还是求助于“!important”吧。只要这样写就可以了:

.div_name {width:80px !important;width:100px;padding:10px;}
因为80+10+10=100。正好让宽度 变成100px。

有时候,我们给一个层加上边框 ,在Firefox里面也会出现宽度增加的情况,比如:

.div_name {width:100px;padding:10px;border:2px solid #ccc;}

上面这个层,在Firefox里面的实际宽度等于100+10+10+2+2=124px,因为边框也会增加宽度。怎么办呢,还是靠“!important”,这样写就可以了:

.div_name {width:76px !important;width:100px;padding:10px;border:2px solid #ccc;}

写CSS经常要做这样的计算,还要写很多!important,苦了设计师们,什么时候IE和Firefox的CSS标准统一就好了。

Mysql数据转移编码问题

MySql的字符集是越来越严格了,涉及到好几个层面的编码。

实用的来说,我们一般就用gb2312或者utf8两种编码(个人严重推荐utf8) ,下面以utf8为例说一下:

1、转移数据的时候,在Create table后面注明字符集为 utf8,数据库校验(collation)字符集为utf8_unicode_ci,比如:

CREATE TABLE `member` (
`id` int(7) NOT NULL auto_increment,
`account` varchar(50) default NULL,
`password` varchar(100) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;

2、客户端读写数据的时候,在select database前面加上SET NAMES ‘utf8′这个语句,这是为了告诉MySql连接校验(connection collation)的字符集也是utf8,比如:

$mysql->host=”localhost”;
$mysql->user=”foor”;
$mysql->pass=”bar”;
$mysql->db=”db”;
$mysql->connect();
mysql_query(”SET NAMES ‘utf8′”);
$mysql->select_db();

这样就搞定了,gb2312也是类似的修改这两层就可以了

推荐系统的演化 (Evolution of online recommendation system)

类似于amazon豆瓣这样的仓库型网站,推荐系统是提高用户黏度、扩大盈利规模的必备手段。

最初的推荐系统其实是类似于黄页的分类系统,比如 bababianyupoo都属于“网络相册”这一类,那么,介绍bababian的时候就可以推荐yupoo,这个系统最耗费成本,而且效率相当低。而且图片等非文本信息很难被分类。

然后进入了tag横行的时代 ,通过UGC模式产生的大量tag,让仓库里的大量条目建立关联,豆瓣采麦的推荐系统就是这么做的。tag可以很好的胜任图片信息的推荐,但是对音乐、艺术等抽象信息就无能为力了。

音乐分享鼻祖Pandora只好不辞辛劳的采用了一种特殊的推荐机制:分析每一首曲目并赋予其独特的音乐DNA标记,通过标记的匹配来进行推荐,在pandora还未封闭之前,它一直是我听歌的首选,推荐的准确度相当高,以至于封闭之后让我无论如何也找不到替代品。

现在又有一种新的推荐模式出现:基于相似族群的推荐。最近去了趟toluu,是做博客推荐的,输入你喜欢的博客网址,系统会自动分析与你爱好相似的用户(把你们归类为同一人群),并把他们喜欢的博客推荐给你(同一人群应该有同样的爱好)。我没仔细去体验toluu的服务,也不好说准确度有多高,但是这个模式的确非常诱人,其实这也是最初采麦想采用的推荐模式,但现在还处于用户基数不够的阶段,尚不是合适机会。

相似族群的推荐更像是朋友之间的悄悄话。口味相似的人,互相从对方身上获取自己未接触过的信息,最后把每个人的小圈圈扩大,所有人都融合到一个大圈圈里,实现1+1=4的平方级增长,符合资源优化配置的趋势。

To Mika:

For websites like amazon and douban, recommendation system is the key element for a higher user stickyness and larger sales.

The original recommendation mechanism is an online yellow page, with different catalogs and each item belongs to one or several catalogs. The item under the same catalog will be recommended automatically. The weak point is yellow page can not define non-text information like pictures.

Then came the TAG era from about 5 years ago. Tag is the most representative feature of web 2.0. With enormous UGC (user generated content) emerging in one night, user added tags become the most efficient way for keyword match and recommendation.

But tag also has fatal weakness: you can never add enough accurate tags to virtual information which involves personal taste, such as books, music, movie. I love adventure movies, but Caribbean Pirates is disgusting for me, while everyone tag it with “adventure”. How can we deal with that?

Pandora invented a complicated system to analyze every song’s DNA (inner pattern), and generates a very high accuracy when recommend new songs to users. Frankly, I damn love pandora. It’s the best product I’ve ever found online. Don’t mention Last.fm to me, it sucks. In China there are exact copiers: YOBO and songtaste. Since pandora shut the door to non-US users, I can only turn to YOBO, but saddly, the recommendation system is like shit.

The final solution for recommendation should be based on human TASTE. Similar people have similar taste. If our system can determine that Tom and Jack is 80% similar people (in some field), then we can reach a 80% accuracy when we recommend TOM’s favorites to Jack, and vice versa. I’m not sure if toluu (a blog recommendation system) is based on this mechanism, but I will definitely spend my whole life on it.