用 CSS3 @font-face 嵌入字体

今天刚发现牛人 Mark Pilgrim 正在写的 Dive Into HTML5,对网站上标题的字体很感兴趣,查了一下,是 Essays 1743.

这个字体以 LGPL 协议发布,并没有普及到大部分计算机上,所以需要用到 CSS3 的字体嵌入技术,Cross Browser Font Embedding with the CSS3 @font-face selector 一文详细讲解了跨浏览器的解决办法。

我已经把本站的头部标题改成使用这个字体,如果你没有看到可能是因为缓存的问题,请刷新一下浏览器。

上面提到的教程其实挺麻烦的,主要是 IE 仅支持 eot 格式字体文件。由于我是复制 Dive Into HTML5 的样式,于是直接从那儿把字体文件下载到我服务器上,再把 CSS 代码搬过来就可以了。

@font-face 定义:

@font-face {
  font-family: "Essays 1743";
  src: url("/static/font/essays1743-min.eot");
  src: local("Essays 1743"), url("/static/font/essays1743-min.ttf")
}

在标题应用该样式:

#header-title {
  font-family: "Essays 1743";
  ...
}

当然了,嵌入字体的做法对中文来说不大适用,因为一个中文字体文件少说几个到十几个 MB, 用户不能忍受,我们的服务器也不一定能够忍受。所以对中文来说,如果只是想标题使用特殊字体,最好做成图片。而这个英文字体文件只有 30 多 KB,和一张图片的大小差不多,如果有大量的文字需要使用该字体,存储、带宽这方面就划算得多了。

外链点击没有 referrer 信息?!

最近经常盯着访问日志,有一次一边 "tail -f" 日志,一边在 Google Reader 中点击了一下自己的一个日志(此处“日志”指 blog post)链接,发现新增的一行日志竟然没有 referrer 信息!

我的浏览器并没有做任何隐藏 referrer 的特殊配置,所以这事儿我纳闷了好多天—— Google 是怎么做到的?即使可以做到,有什么必要隐藏 referrer 呢?

今天晚上动用了一大堆工具——Firebug, Fiddler, Eventbug, 研究了半天,我想 Google 一定是在用 JavaScript 完成这样的 trick.

后来突然想明白了,我的 Google Reader 一直是使用 https 连接的(避免意想不到的 connection reset),这不是 Google 做的,而是浏览器的默认行为。这么做很有必要,保护用户的隐私。把 https 换成 http 再点击,发现请求头中确实加入了 referrer 字段。据我所知,SearchStatus 这个扩展在遇到 https 页面的时候也是不会向外作任何查询的。

根据我做的山寨测试,IE, Firefox, Opera 都是这么做的,很好。微软还有一篇 support article 说这个事,里面提到:

many secure (HTTPS) Web servers store secure information such as credit-card data in the URL

我想现在应该很少有网站这么做了,不过 url 里面还是很容易找到涉及隐私的信息。隐藏 referrer 虽然给做 web analytics 的人带来了干扰,仍然是非常必要的。

在解除这个困惑的过程中,看到几年前就有人发现在 AdWords 中点击广告链接测试的时候,没有 referrer header,很奇怪,这几年内也没有人给他正确的答案。我刚刚给了他一个 comment,希望可以解惑……

这大概也可以解释为什么我们看到自己网站统计中没多少从 Google Reader 过来的流量吧(至少我的是这样)——因为大家都得 "s".

叩手礼

几天前的一个晚上几个人一起吃饭聊天,席间有人给另一个人茶杯倒水,那人就用手指在自己茶杯旁边敲桌子。

我注意到了,就比较好奇地问这是什么意思?他就给我解释了一番,大致就是百度百科里的“叩手礼”这个页面所说的。

奇怪的是我们几个中国人都不知道这个礼节和这个典故,知道的都是外国人,让人感觉有点惭愧……

可能这个礼节还是流行于喜欢喝茶的广东、香港人中间,像我这样从来不喝茶的北方人不懂也是可以理解的。

有个外国人说他来中国前找了个人教他在中国怎么“客气”,于是他就学到了这个。今晚我们又和他一起吃饭,别人倒茶的时候,本该致谢的那个就边敲桌子边说:“快点,快点!”

SQL Server 无法修改表,超时时间已到

SQL Server 一张表存储大量数据的时候,对表结构作修改就非常耗时了。其实耗时还好说,我们年轻,有的是时间……最怕的是它觉得太耗时就放弃给你修改了。这几天想给某个表加个字段,就遇到了这样的问题。点了保存后过一段时间,就会弹出个对话框说:

无法修改表。超时时间已到,在操作完成之前超时时间已过或服务器未响应

解决办法:在 SQL Server Management Studio 里,通过菜单“工具-选项”打开选项对话框。在左侧寻找“设计器-表设计器和数据库设计器”,然后在右侧勾选“为表设计器更新重写连接字符串的超时值”,在它下面的“事务超时时间”默认应该是 30 秒,我们应该把它改得稍微大一些,不过好像不能超过65535.

微软的软件报错的方式很像某些部门的声明──令人费解,这是它一贯的作风。

话说我本来是比较不喜欢用 SQL Server 的,尤其是刚开始的时候遇到太多气人的问题,可是由于工作原因又不得不用。不过当那些让人郁闷的问题一个一个解决掉的时候,它也就不那么烦人了。

Ruby 的一个陷阱

今天是 2010-01-25. 我在 irb 中测试 Date 类的 today 方法:

>> (Date.today -1 ).to_s
=> "2010-01-25"
>> (Date.today - 1).to_s
=> "2010-01-24"
>> (Date.today-1).to_s
=> "2010-01-24"

结果多少让人有点吃惊。第一次我输入太快发生了错误,减号和 1 之间的空格被我敲到 1 后面去了,但是两次结果竟然不一样!

不过我很快回过神来了,第一次输入,Ruby 把 -1 解释成为 today 方法的参数了。因为 Ruby 的方法调用可以不加括号,虽然不鼓励所有的函数调用都这么干,但是去掉一对空的括号是被鼓励的(ref)。例如 puts,我就没见过有人调用它会加括号。

再看第三个输入,那些对空格很吝啬的人也不会遇到这样的问题,除非他不小心在减号前打了一个空格。运算符和操作数之间的空格竟然影响了程序的解释结果,这让人很纠结。为了保险起见,我还是给这个方法调用加上了一对空的括号。

假如 Ruby 像其它语言一样要求方法调用必须加括号,这个问题就不会存在。对于解释型语言来说,语法的灵活很可能导致解释效率的降低。不过这么多人喜欢 Ruby,也有一部分原因是它跟其它语言很不一样。

我忽然想到,如果大学里面有 Ruby 课程(千万不要是必修,把大学变成培训班),肯定会有某些老师把上面的这个小把戏作为考试题,看着学生们出错得意地笑。就如同考察逻辑运算符的优先级一样无聊,其实只要记住括号的优先级最高就行了。

另外,假如 Ruby 像其它语言一样要求方法调用必须加括号,有的 callback 实现就会更简单。把方法作为参数传递的时候,像 Python 一样直接写方法名不就可以了吗?不行,这是一个方法,方法调用不必要加括号,Ruby 解释器发现了方法名就会尝试执行它。所以得写成 "method(:my_callback)",才能传入一个 Method object. 又因为这是一个 Method object,所以调用它的时候也不能像 Python 一样简单地写 "callback(...)" 了,需要写成 "callback.call(...)".

看来“可省略的括号”使得这种思路的实现复杂化了,不过似乎 block 也是无所不能……

Latest Comments
  • 最新评论与站内搜索 1
    "强大" - by SillySnail
  • 外链点击没有 referrer 信息?! 2
    "@zhang 嗯,analytics 是这样,不过如果能够从日志中分析数据的话,..." - by qingbo
  • 外链点击没有 referrer 信息?! 2
    "Google Reader的域名和Google的一样,从Reader来的也看不出..." - by zhang
  • 轻轻松松用代理 - Your Freedom 4
    "Your Freedom 被封掉了,我日死GFW,太他妈龌龊" - by xxx