Nirvana Studio » Web?? :: 分享知识,传播技术

Archive for the 'Web??' Category

FireBug 控制台函数说明

Posted by Nicholas Ding on 20th 九月 2006

原文地址:http://www.joehewitt.com/software/firebug/docs.php

FireBug 是一个非常实用的JavaScript以及DOM查看调试工具,是 Firefox 的一个插件。使用 FireBug 调试 AJAX 应用非常方便,终于可以告别 alert 时代了!

Console Logging 函数

FireBug 为所有 Web 页面提供了一个 console 对象。这个对象有以下函数:

Logging 基础

console.log(”message” [,objects]) - 将一个字符串打印到控制台。字符串可以包含任何“String Formatting”小节描述的模式。字符串后面的对象应该用来取代之前字符串中的模式。(译者注:大家用过C里面 printf 吧,效果基本是一样的。)

Logging 等级

通常根据不同的等级来区分Logging的严重程度是很有帮助的。FireBug 提供了4个等级。为了达到视觉分离的效果,这些函数与 log 不同的地方就是它们在被调用的时候会自动包含一个指向代码行数的链接。

console.debug(”message” [,objects]) - 记录一个 debug 消息。
console.info(”message” [,objects]) - 记录一个信息.
console.warn(”message” [,objects]) - 记录一个警告.
console.error(”message” [,objects]) - 记录一个错误.

断言

断言是一条确保代码规则的非常好的途径。console 对象包含了一系列各种类型的断言函数,并且允许你编写自己的断言函数。

console.assert(a, “message” [,objects]) - Asserts that an a is true.
console.assertEquals(a, b, “message” [,objects]) - Asserts that a is equal to b.
console.assertNotEquals(a, b, “message” [,objects]) - Asserts that a is not equal to b.
console.assertGreater(a, b, “message” [,objects]) - Asserts that a is greater than b.
console.assertNotGreater(a, b, “message” [,objects]) - Asserts that a is not greater than b.
console.assertLess(a, b, “message” [,objects]) - Asserts that a is less than b.
console.assertNotLess(a, b, “message” [,objects]) - Asserts that a is not less than b.
console.assertContains(a, b, “message” [,objects]) - Asserts that a is in the array b.
console.assertNotContains(a, b, “message” [,objects]) - Asserts that a is not in the array b.
console.assertTrue(a, “message” [,objects]) - Asserts that a is equal to true.
console.assertFalse(a, “message” [,objects]) - Asserts that a is equal to false.
console.assertNull(a, “message” [,objects]) - Asserts that a is equal to null.
console.assertNotNull(a, “message” [,objects]) - Asserts that a is not equal to null.
console.assertUndefined(a, “message” [,objects]) - Asserts that a is equal to undefined.
console.assertNotUndefined(a, “message” [,objects]) - Asserts that a is not equal to undefined.
console.assertInstanceOf(a, b, “message” [,objects]) - Asserts that a is an instance of type b.
console.assertNotInstanceOf(a, b, “message” [,objects]) - Asserts that a is not an instance of type b.
console.assertTypeOf(a, b, “message” [,objects]) - Asserts that the type of a is equal to the string b.
console.assertNotTypeOf(a, b, “message” [,objects]) - Asserts that the type of a is not equal to the string b.

测量(Measurement)

下面的一些函数可以让你方便的测量你的一些代码。

console.trace() - 记录执行点的堆栈信息。
console.time(”name”) - 根据 name 创建一个唯一的计时器。
console.timeEnd(”name”) - 根据 name 停止计时器,并且记录消耗的时间,以毫秒为单位。
console.count(”name”) - 记录该行代码执行的次数。

字符串格式化

所有 console 的 logging 函数都可以通过以下模式格式化字符串:

%s - 将对象格式化为字符串。
%d, %i, %l, %f - 将对象格式化为数字。
%o - 将对象格式化成一个指向 inspector 的超链接。
%1.o, %2.0, etc.. - 将对象格式化成包含自己属性的可交互的表格。
%.o - 将对象格式化成具有自身属性的一个数组。
%x - 将对象格式化成一个可交互的 XML 树形结构。
%1.x, %2.x, etc.. - 将对象格式化成一个可交互的 XML 数型结构,并且展开 n 层节点。

如果你需要一个真实的 % 符号,你可以通过一个转移符号就像这样 “\%”。

命令行函数

内建的命令行函数可以通过以下命令行使用:

$(”id”) - document.getElementById() 的简写。(译者注:跟 prototype.js 学来的吧?)
$$(”css”) - 返回一个符合 CSS 选择器的元素数组。
$x(”xpath”) - 返回一个符合 XPath 选择器的元素数组。
$0 - 返回最近被检查(inspected)的对象。
$1 - 返回最近被检查(inspected)的下一个对象。
$n(5) - 返回最近被检查的第n个对象。
inspect(object) - 将对象显示在 Inspector 中。
dir(object) - 返回一个对象的属性名数组。(译者注:跟 Python 学的?)
clear() - 清除控制台信息。

Posted in Ajax, JavaScript, Web?? | 7 Comments »

编写自己的dojo扩展

Posted by Nicholas Ding on 12th 八月 2006

前言

dojo是时下非常流行的javascript框架,它在自己的Wiki上给自己下了一个定义,dojo是一个用JavaScript编写的开源的DHTML工具箱。

dojo很想做一个“大一统”的工具箱,不仅仅是浏览器层面的,野心还是很大的。不过dojo带来了JavaScript编程的一些新想法,其中引入包机制进行动态加载是一个不错的概念。

理解dojo的包机制

其实dojo只需要一些很小的加载代码就可以用来加载它的各种包,它的官方站点上提供的dojo-ajax下载中包含的dojo.js体积还是比较庞大的,因为它将一些常用的包都包含在了js中,

但是很多时候我们并不需要这么多功能,还是按需加载比较好。

幸好在http://download.dojotoolkit.org/这个地址中我们还可以下载到dojo的各个自定义版本,其实包含的组件都是一样的,只不过dojo.js的大小有很大不同,那么,我们就从minimal版本下手。

下载之后会发现minimal版本包含的dojo.js只有18kb,里面仅仅包含了加载机制,非常不错。这样,我们就可以开始编写自己的dojo扩展。

dojo代码结构

解压缩后的目录里面包含src目录,src目录下存放有dojo的各个组件包,我们在这里面新建一个hello目录。

新建一个名为__package__.js文件,很类似Python的模块命名,这个__package__.js定义了在引入这个命名空间的时候默认导入多少类,以及这个命名空间的名字。

我们的目的是做一个dojo.hello.Echo扩展,那么在__package__.js中的代码应该这样:

// kwCompoundRequire 的作用是当你导入整个dojo.hello包的时候需要默认加载多少类
// 这些定义就在这个函数里面,common在这里表示默认的加载,这个参数不是固定的
// dojo希望自己是一个“大一统”的实现,所以考虑了非浏览器情况,可以有别的,譬如rhino
dojo.kwCompoundRequire({
	common: [
		"dojo.hello.Echo"
	]
});
// 这个定义了包,默认这么写 | 原因嘛,当然是有的,看你的悟性了:-)
dojo.provide("dojo.hello.*");

我们指定了默认加载的类Echo,那么我们就去写Echo类,在hello目录中新建Echo.js,代码如下:

// 类名定义,JavaScript写的变扭,其实就是直接定义类名
dojo.provide("dojo.hello.Echo");
 
// 类定义部分,非常熟悉的代码
dojo.hello.Echo = function() {
	this.name = "dojo.hello.Echo";
	this.sayHello = function(greeting) {
		return greeting;
	}
}

扩展写好了,很简单,接下来就是掉用了,index.html如下。

<html>
<head>
<script language="javascript" src="dojo.js"></script>
<script language="javascript">
dojo.require("dojo.hello.*");
var echo = new dojo.hello.Echo();
document.write(echo.sayHello("Hello World"));
</script>
</head>
<body>

</body>
</html>

注意dojo.require(”dojo.hello.*”)回去请求两个文件,首先是__package__.js,这样一来就得到了之前在dojo.kwCompoundRequire里面指定的类列表,然后去加载Echo.js。你也可以直

接去加载Echo.js,只需要变成dojo.require("dojo.hello.Echo")

更多内容

这个例子非常简单的介绍了一下dojo的包加载机制,当然这个包中的类并没有引用其它类,dojo还允许在代码中动态加载其它类,当然了,这些都是通过XmlHttp来实现的,因为是同步模式,所以请求的类比较多并且都没有包含在dojo.js中的时候会有页面停顿的现象,这点还是需要注意的。

文中的代码下载:,dojo-hello.tar.gz

一些dojo的资源:

Posted in Ajax, JavaScript, Web?? | No Comments »

什么是 1% 规则?

Posted by ShiningRay on 20th 七月 2006

作者:Charles ArthurThe Guardian
翻译:ShiningRay

一个正在浮现的规则告诉我们——如果你的网站有100个人(一组)的在线量,只有1个会创建新的内容,有 10 个会与之进行交互(回复或者提供改进) ,剩下的89个就仅仅浏览一下。

在YouTube的统计数据中也显示出了几乎一样的情况。YouTube在18个月内就从零开始,占据了现在所有在线视频浏览的60%的份额。

数据显示出:每天有10亿次下载以及6,5000次上传——正如 Antony Mayfield所指出的那样,每次上传有1,538次下载——每个独立用户每月20m。

这个数据中的“创作者对消费者”的比率只有0.5%,不过是现在下最终解决还比较早,因为还不是所有人都发现了YouTube(还有就是下载比上传要方便得多,因为任何网页都能包含YouTube的链接)。

再思考一些其他的依赖社区产生内容的项目的统计数据,Wikipedia:Wikipedia所有文章的50%的编辑工作是由0.7%的用户来完成的,而有超过70%的文章是由1.8%的用户来撰写的。该数据来自Church of the Customer的Blog

从一些社区网站收集的早期的数据显示大约80%的内容是由20%的用户产生的,但是不断增长的数据量给出了清晰的图景,告诉我们Web 2.0的网站应该如何去思考。例如,一个网站如果是要求大量的用户交互和从用户创建的内容的话,它会发现10个人中有9个只是路过而已。

Yahoo的Bradley Horowitz指出相同的情况也适用于Yahoo:在Yahoo Groups(Yahoo的讨论组)上,“用户人口中的1%可能会创建一个讨论组;10%的用户可能会参与地比较活跃,同时实际创作新的内容——开启一个新的主题或者回复已有的主题;100%的用户可以从前面的用户的活动中受益,”他于二月份在其Blog上谈论了这一点

那么结论是什么?就是你不能对在线的用户期待太多。。问题在于——和现实生活一样——是如何找到构建者。

Posted in Web?? | 12 Comments »

Web 2.0

Posted by ShiningRay on 5th 四月 2006

{本文由Nirvana StudioShiningRay 翻译、Sometimes 审校,原文来自英文维基百科,本文档按照GNU自由文档许可证发布,已转给中文维基百科,最新版本请查阅 http://zh.wikipedia.org/wiki/Web_2.0 ,您可以自由分发、修改,必须按照GNU自由文档许可证}

Web 2.0是一个新生的术语,它的应用可以让人了解目前万维网正在进行的一种改变——从一系列网站到一个成熟的为最终用户提供网络应用的服务平台。这种概念的支持者期望Web 2.0服务将在很多用途上最终取代桌面计算机应用。

概览

Web(在这里,指代“Web 1.0”)最早的概念包括不常更新(甚至不更新)的静态HTML页面。而.com时代的成功则是依靠一个更加动态的Web(指代“Web 1.5”),其中CMS(内容管理系统)可以从不断变化的内容数据库中即时生成动态HTML页面。从这两种意义上来说,所谓的眼球效应则被认为是Web感受内在的东西,也因此页面点击率和外观成为了重要因素。

Web 2.0的支持者认为Web的使用正日渐以交互性和未来的社会性网络为导向,所提供的服务内容,通过或不通过创建一个可视的、交互的网页来充分挖掘网络效应。某种观点认为,和传统网站相比,Web 2.0的网站更多表现为Point of presence或者是依赖用户的门户网站

 

该词的来源

这个术语是由O'Reilly Media的Dale Dougherty 和 MediaLive 的 Craig Cline 在共同合作的头脑风暴会议上,提出来的。Dougherty提出了Web目前正处于复兴时期,有着不断改变的规则和不断演化的商业模式。而Dougherty则是举例说明——“双击是Web 1.0,Google AdSense 则是Web 2.0。 Ofoto是Web 1.0;Flickr 则是Web 2.0”,而不是给出确切的定义,和补充一个商业前景,同时O'Reilly Media、Battelle和MediaLive 在2004年10月启动了第一个Web 2.0大会。第二次的年会将在2005年10月举办。

在他们的会议开场白上,O'Reilly和Battelle总结了他们认为的表现了Web 2.0应用特色的一些关键原则:

  • 将Web作为平台;
  • 将数据变成“Intel Inside”;
  • 分享和参与的架构 驱动的网络效应;
  • 通过带动分散的、独立的开发者把各个系统和网站组合形成大汇集的改革;
  • 通过内容和服务的联合使轻量的业务模型可行;
  • 软件采购循环的终结(“永久的Beta版”)
  • 软件凌驾于单一设备的层次之上;
  • 拉动长尾的能力;

这种软件发布中的版本号的使用从某一方面也暗示了整个Web已经被看作是一种有着重大增值意义的新产品,而且正在被重写编写和发布。

 

同语义网的比较

Web 2.0这个词的一个较早的出现是作为语义网的同义词。这两个概念有点相似而且是互补的。结合了基于标签的Floksonomy的社会性网络系统如FOAFXFN,以及通过BlogWiki进行发表,已经创建了一个语义环境的天然基础。

 

技术

Web 2.0技术基础比较复杂而且还在演化中,但可以肯定的是包括服务器端软件、内容联合组织、消息协议、基于标准的浏览器和各种不同的客户端应用程序。(一般会避免使用非标准浏览器的一些增强功能和插件)这些不同但是互补的方法提供了Web2.0信息存储、创建和分发的能力,这些能力远远超出了先前人们对网站的期望。

如果一个网站使用了以下一些技术作为特色的话,就说他是利用了Web 2.0技术:

技术方面:

  • CSS, 语义化有效的XHTML标记,和Microformats
  • 不突出的丰富应用技术(例如Ajax
  • 数据的联合,RSS/ATOM
  • RSS/ATOM数据的聚合
  • 规则且有意义的URL
  • 支持对网志发帖子
  • REST 或者是XML Web服务API
  • 某些社会性网络方面

通用概念:

  • 网站不能是封闭的——它必须可以很方便地被其他系统获取或写入数据。
  • 用户应该在网站上拥有他们自己的数据。
  • 完全地基于Web —— 大多数成功的Web 2.0网站可以几乎完全通过浏览器来使用

 

内容联合组织

Web 2.0的首要的也是最重要的发展,包括了使用标准化协议的网站内容的联合,这可以让最终用户在其他环境中使用网站的数据,包括另一个网站、浏览器插件、或者一个单独的桌面应用程序。这些联合协议包括RSS资源描述框架(RDF),和Atom,这些都是基于XML的。特别的协议如FOAFXFN(XHTML朋友网络)——这两者都是为了社会性网络开发的——扩展了网站的功能或者可让最终用户不集中于网站就可以进行交互。参见microformats,以查询更多的专门数据格式。

由于发展太快,很多这些协议都是事实上的标准而不是正式的标准。

Web服务

双向的消息协议是Web 2.0架构的关键元素之一。两个主要的类型是RESTfulSOAP方法。REST(Representational State Transfer)表示了一种Web服务 客户端传送所有的事务的状态。SOAP(Simple Object Access Protocal)和类似的轻量方法都依赖服务器来保存状态信息。两种情况下,服务是通过一个API调用的。这个API常常是根据网站的特殊需求定义的,但是标准的Web服务API(例如,给Blog发帖)的API依然被广泛使用。一般来说Web服务的通用语言是XML,但并不一定,还存在大量不同的其他语言,如JSONYAML等。

最近,出现了一个被称之为Ajax的混合形式,用来增强基于浏览器的Web应用的用户体验。这可以用于一些特别的形式(如Google Maps)或是一些开放的形式,可以直接利用Web服务API、数据联合,甚至是绘画。

宽泛得说,联合是一种Web服务的形式,但是Web服务形式的使用却不是很常见的。

参见 WSDL(Web服务描述语言)和Web服务规范表 .

 

服务器软件

Web 2.0 的功能是在已有的Web服务器架构上建立的,但是更加强调后台软件。数据联合不仅仅是名称上和内容管理发布方法不同,而且Web服务要求更加强壮的数据库工作流的支持,并且变得与传统的企业内部网的应用服务器功能更加相似。供应商不管是用一个通用服务器方法,可以把所有需要的功能都集中到一个服务器平台上,或者是一个Web服务器插件的方法,可以使用增强了API接口的标准发布工具和其他工具。不管选择的是哪种途径,Web 2.0的进化不会为这些选择做出重大改变。

 

社会影响

Web 2.0中出现的数据联合和消息传送能力,提出了潜在的一种可能性——在完全不同的在线社区之间创建一个更加紧密的社会构造。同时还出现了一些新的术语来集合性地代表这些共同的社团,包括blogshpere网志的世界,syndisphere:内容联合发布,以及 wikisphere,然而其他的观察者认为这些措辞和内在的含义太空泛了。

 

商业影响

可能的由WEB2.0带来的指数级增长的业务的原因,可归结为以人为本的消费和以计算机为本的消费的区别。

对于价值的鉴定和消费的过程中无需不同人为参与,由于Web2.0的出现,也是完全可能的事情了。各个组织会不断使用诸如RSS/Atom/RDF之类的联合格式来联合他们的价值提案。除了价值的联合外,Web服务终点发布将简化联合的价值的消费过程。

 

外部链接

例子

这些公司,被认为是获得了巨大的成功的主要的“Web 1.0”网站,提供某些内容联合和Web服务相结合的服务:

这些公司被广泛认为是Web2.0的范例:

Posted in Web?? | No Comments »

HTTP代理缓存

Posted by ShiningRay on 5th 四月 2006

原文地址:http://vancouver-webpages.com/proxy.html

翻译:ShiningRay @ Nirvana Studio

什么是代理缓存?
下面是使用代理服务器的三大理由:

  1. 因为你在防火墙背后(为了安全),因此必须使用。

  2. 因为使用缓存可以显著提高任何人的页面浏览速度。

  3. 因为对于你的机器,你没有足够的“真实”IP可用。

如果你在防火墙后面,那么你其实可能已经使用了一个代理。否则,你要考虑安装一个。

Netscape Navigator 和一些其他较新的浏览器内建了缓存机制。在一个单用户系统中,诸如使用拨号的PC机,这应该足够了。你可以调整缓存参数让缓存变得大一点,或更频繁地检查缓存条目。顺带提一下,在Netscape中,“刷新”通常不会去获取一份文档完全最新的副本,他会发送一个GET If-Modified-Since以及Pragma: no-cache。按下Shift再按“刷新”会强制所有页面框架都通过发送Pragma: no-cache来完全从来源重新加载。如果要在Netscape中查询磁盘缓存输入about:cache。

即使在单个系统上,如果你使用多于一个的浏览器或者有多于一个的用户,一个代理缓存也许会更有效,因为缓存的文档可以在各种媒介中共享。

LAN系统

多个用户在LAN中使用代理就可以产生的真正的好处。由任何一个人访问的任何一个新的页面都会被存储在缓存中。下一个同样访问这个页面的人将直接获取缓存了的副本,以完全的LAN的网速,而不用再去访问源地址。这可能会快1000倍甚至更多。

针对Windows系统:

配置浏览器的代理

一些浏览器可能只接受一个值,例如(在Unix中)可以通过使用 setenv http_proxy http://somewhere.org:80/。某些域名可以被排除,通过使用 setenv no_proxy some.org,some.other.org。其他浏览器,如Netscape,有一个更复杂的方式来支持多种代理。Netscape还有一个通过使用JavaScript来自动处理代理的方式。Mosaic-2.7页运行代理列表。

绕过缓存

如果一个HTTP请求含有
Pragma:
no-cache

的头,那么缓存就会被指向获取一个新的副本。可能它自己也会保存一个新的副本。在Netscape、Mosaic和Lynx(可能所有的浏览器)中使用刷新都会发送一个带有这个头的请求。

可缓存和不可缓存的文档

一般的HTML文档通常都是可以缓存的。缓存代理一般要求一个有效的Last-Modified头,同时可能不缓存大于某个尺寸或主题受限制的对象。由CGI脚本生成的HTML文档通过生成合法的Expires头来变得可缓存(或不可),虽然某些代理不会缓存带有“cgi-bin”或查询字符串的URL。要求身份验证的文档一般都不会被缓存。Netscape有一个选项让你可以从本地缓存SSL服务器上获取的文档。如果你打开了这个选项,其他获得了你的机器访问权限的人(很有可能是窃取的)就可以读取你近期的安全事务。

注意不同的缓存服务器也许在解释HTTP标准上会略有不同,所以某一个可以缓存的文档不一定能被另一个所缓存。

缓存控制和CGI

我使用缓存测试脚本针对Apache 1.1.1和Squid 1.0.5进行测试,获得了以下结果:I

Expires

Last-Modified

Apache

Squid

Tonight

Last
Night

缓存

缓存

+1
minute

Last
Night

Expires

Expires

Tonight

none

Not Cached

Cached

none

none

Not
Cached

Cached

0

Last
Night

Not
Cached

Not
Cached

Last
Night

Last
Night

Not
Cached

Not
Cached

Tonight

Tonight

Cached

Cached

Tonight

0

Not
Cached

Cached

Squid缓存的默认配置是不去缓存中间有“cgi-bin”和“?”的URL,我去掉了这个配置,获得了这种结果。

RFC1945 (HTTP1.0标准)说Expires过期时间等于或早于Date头的值,接受者便不能缓存文档。零值(0)或一个非法的日期格式被认为等同于“立刻失效”。

建议在CGI脚本中使用:如果CGI脚本的输出确实是一个静态的文档,对于同一个查询字符串(如/cgi-bin/search?query=food)有同样的内容,那么可以生成一个合适的Last-Modified字段(最后修改日期),以RFC1123的格式。如果输出的内容在某个特定的时间段内是合法的,那么生成合适的Expires头。如果输出的内容里立刻就要失效,或者失笑于某个特定时间,则生成一个Expires头等同于当前时间或一个非法值。

为了能更好的使用全部的带宽,尽可能地多缓存东西。也就是说,例如,如果你有一个网络摄像头,显示办公室窗口内的景象,你也许可以生成一个Expires头10分钟或更多。

服务器端包含(SSI)

Apache, NCSA, 以及一些其他的服务器可以在HTML(.shtml)中使用服务器端包含(Server-Side Include)。由于文档的内容是由几个被引用的文件组成的,服务器一般不会设置一个Last-Modified日期或者Content-Length。相应的,这类文档是无法缓存的(因此也要比其他使用缓存的人载入慢很多)。Apache支持一个选项叫做XBitHack,它可以发送一个Last-Modified日期。如果你用了这个,你必须在任何一个被引用的文件更改的时候,把.shtml包装器文件更改为最新时间(Unix命令为touch),否则其他使用缓存的人将无法看到你的新文档除非他们明确使用更新。

Content-Negotiation(内容判断)

如果正在使用内容判断,来提供不同的语言或图像类型,那么对于不同的内容可能只有一个URL。相应地,这样Apache服务器就不会设置Last-Modified。这个问题在HTTP1.1草案中已经通过Vary头来解决。

文档过期

代理缓存会看Expires(过期)头同时使用它在缓存中设置一个失效的日期。如果不存在这个HTTP头,那么将假设为默认的生命周期。这时我不知道代理检查了HTML内容中的META标签;然而CERN以及新的Apache服务器可能会使用一个元数据文件方案来在文档头中生成额外的字段如Expires。CGI脚本也可以使用类似LWP
Perl的库来生成合适的字段。一个非法的Expires头,例如0、负数等,也会使文档无法缓存(里可以失效)。

谁在使用代理

尽管RFC1945推荐不要更改User-Agent字段,特定的代理仍会这样,于是我们可以通过它来统计信息。大约8%的浏览本页面的用户使用以下的代理之一:

  • CERN-HTTPD

  • Harvest Cache

  • Squid Cache

所有在防火墙之后的用户必须使用代理,虽然缓存是完全另一个问题。SOCKS则是一个无缓存的代理方式。

NLANR
缓存项目

看看NLANR的分布式缓存项目!

未来

HTTP1.1(ds.internic.net正在制作草案)有更多针对代理服务器的方案。我们也许可以拥有很多交互的代理缓存可以极高地提高整个互联网。任何有快于14.4kbps moderm的人都会受益。

另一个发展是预抓取代理缓存,例如 Wcol: WWW Collector。这里,这个代理积极的提前寻找相关的图像和页面。原来仅针对Mosaic提速,现在他可以和一个层次缓存机制相互协作当用户读取了第一个页面之后来获取相关的页面。

Posted in Web?? | No Comments »

为什么Flickr不进行自动化测试?

Posted by ShiningRay on 3rd 四月 2006

原文:为什么Flickr不进行自动化测试? — Carlos Villela @ 8:00 pm

Sam Newman 惊讶于(中文版) Flickr没有使用很多自动化测试,因为“作为一个姿态鲜明和成功的应用,我只能假设自动化测试还存在一个更加成熟的途径”。

事实上,当看到的时候我也有点惊讶,不过我想我知道他们为什么不真正十分关心测试的原因,我的反应是他们不仅仅只是一群
过时.COM时代的普通牛仔,在一边把代码仍在墙上一边看看堵住了什么——这些人常常被一般的敏捷人(agilist,还和拳击手pugilist押韵?)在会议和论文上批评他们没有测试自己的代码并被告知这样做更好。
也许有某些原因可以不去麻烦测试,我在这里要尝试在这里解释他们,当然我明白这篇贴子可能有点过激。首先,让我们提出在一个新的项目阶段开始后,两种不同的场景,其中数字代表某种在给定的期间内的想象的成本单元:

场景 A B
开发 10 10
自动化测试 8 0
维护 2 10

假设其他条件均相同,同时代码是由合格的开发者——当然Flickr的家伙们肯定都是——很好地书写的,这样的表格看起来似乎可信:其中A使用了自动化测试来发现错误,节省了维护的时间,而B单独把时间花费在维护上,产生了同样的结果(至少在这个阶段)。

A中,公司需要预付钱来建立可用的测试套件并运行,这样他们就不用对未来的维护多花费这笔钱。现在飞过来了叉子和火把,并且要置我于死地,但是这是一个糟糕的财政决定,除非写自动测试的成本比进行所有的维护的成本要低,但后者的成本可能会扩散。
。然而这个成本不低的风险,至少在我的经验里,看起来比大多数公司所愿意接受的要高的多,因此我们从多数——如果不是全部的——敏捷人那里听到关于这个方式的好的结果

现在再把这小段话引用一下:
我是一个自动化测试的爱好者因为我见过维护软件有多烦人 ,在几个月都不停做这事,消耗尽了我最后一点出现在我可怜精神中的愉快感。我则更偏好写全新的代码,即使代码没有在最终的产品环境中用到,就像测试代码一样,
而不是经历另一个令人沮丧的一天不停地在调试器上一步步移动。 我确定Sam和大多数正在阅读本文的人都是同一条船上的。

B,在我的理论中,就是Flickr所正在做的:
较少的预期投入和随着时间流逝的更多的维护成本。
作为一个开始阶段(嗯,不管怎样,在他们被Yahoo收购之前),这很有意义:
整个启动阶段就是让你可以去做更有风险的事情,同时某种程度上他们臆测
自动地测试任何东西除了小部分重要的(冒烟测试?)并不如立刻把代码颁布出门,且快速,并强制听取用户的反馈并作出反应来得更加重要。这也许要求对对细节和承诺的关注保持一种疯狂的关注程度,这是很稀罕的,不过我要补充一点,这却是我所总结他们成功的原因的一个重要的部分。

正如Joel Spolsky所写的,大概三年前,针对一个类似的情况:

你需要某种经济模型来决定如何花费你有限的资源。你不可能通过说
“压力测试是一个没脑子的东西”或者“服务器也许还可以撑一下。”之类的话来作出可靠的理智的决定。
这些都是感情用事的脑子的大便,而非分析。同时在长期的运行中,我们科学家将会获胜。

所以,我不确定谁是正确的,这里:我知道我所参与的大部分项目,在没有经过自动化测试和大量的测试覆盖率保持工作的情况下,本应该完全失败的(某些事实上就是)。但是再说,我从来没有进行过任何像Flickr这样的起始工作。

Posted in Web??, 测试 | No Comments »

Web 2.0需要测试

Posted by ShiningRay on 3rd 四月 2006

原文: Web 2.0 needs testing 作者:Sam Newman

翻译:ShiningRay @ Nirvana Studio

我带着很多怀疑,耐着性子看完了Cal Henderson的高度富有娱乐性的(而且推荐大家观看)
构建Flickr作坊》,
从中听说自动化测试在他们的优先级列表中并不是特别地高
(有趣的旁白——Cal还认为面向对象编程是“神经错乱的”,所有的“健全”的代码则在“一超大函数”编程和OO之间的空间中存在)。
“测试Web应用”Cal说,“很困难”。其实这是一个普遍的误解。像任何其他应用的类型一样,只要你针对测试性设计了结构,测试是很容易的。然而,同时如果你采用了针对Web应用的测试而制作的测试工具(FITFITnesse, 以及Selenium都是很好的例子),那么即使那些没有带着测试的概念写的应用都没有借口说不利用他们进行开发。

但是现在放在我们面前的是Flickr这样一个姿态鲜明成功的应用,我只能假设自动化测试还存在一个更加成熟的途径。这种对自动化测试的放任自由的方式是不是很普遍呢?

让我们看看这另一条道路。如果你没有自动化测试,你要么手工进行测试(这意味着更长的发布时间)要么干脆不测试。如果你要着眼于交付有质量的产品,这也许意味着你最终还是要做很多手工测试,而这些测试本来可以自动化地更快完成的,甚至只要你想,可以在
在每一次的代码提交中完成

Web的架构产生了一个及早的快速发布、同时有一个经常发布的过程这样的想法。有了Web,你所有要关心的最终目标环境仅仅是你的服务器和客户端的浏览器。推出一个发行版真的可以像Flickr使用的“一点部署”(One-click Deployment)。有了一个成熟的测试框架,如果有必要的话,还可以办到一天之内多次直接给你的用户发布。

测试也许看起来不怎么好玩——但是一旦你明白了它意味着你可以更频繁地对你的用户发布更酷的功能,同时你可以在修复Bug上花费更少的时间,那么我们都可以去更加喜欢书写测试了。

Posted in Web??, 测试 | No Comments »

缓存友好的网页

Posted by ShiningRay on 3rd 四月 2006

缓存友好的网页

by Jennifer Vesperman 03/07/2002 原文地址:http://www.linuxdevcenter.com/pub/a/linux/2002/02/28/cachefriendly.html

翻译:ShiningRay @ Nirvana Studio

现在我们有很多HTTP缓存。他们存放你的页面多久呢?他们应该存放多久呢?RFC 2616(HTTP/1.1)指出了缓存必须遵循Expires和Cache-Control头——那么你的页面是否都有呢?

“在HTTP/1.1种的缓存的目的是为了在很多情况下消除发送请求的需要,同时在其他一些情况下消除发送完整的响应的需要。” RFC 2616

缓存友好页面的优点

“当缓存可以完全避免对原始服务器发送请求时,HTTP缓存的工作是最佳的。避免请求的主要机制是,针对原始服务器提供未来的一个确切的失效时间,表示一个响应可以被用来满足后续的请求。换句话说,一个缓存可以返回一个新的响应而不必先联系服务器。”RFC 2616

RFC写的时候是期望网页要包含失效期头的。如果谨慎地选择头中的失效时间,缓存可以不失去任何意义来提供存储了的页面。

当原始服务器不提供失效头时,缓存根据诸如“Last-Modified”之类的头来推断,猜测出一个合适的失效时间。与由了解页面内容以及更改频率的人设置的失效日期相比,推断的方法显然效率较低。

“由于推断的失效时间也许会降低语义透明度,应该被谨慎使用,同时我们鼓励原始服务器尽可能提供确切的失效时间。”RFC 2616

关于缓存的注意事项

HTTP/1.1标准(第13节)关于缓存有一个强制的要求:它要求他们提供语义的透明——返回一个缓存了的响应必须提供本来从原始服务器上获取的同样的数据;同时它提倡读取原始服务器和客户端所提供的新鲜度要求。

缓存必须传递由上游缓存或者是原始服务器提供的警告,而且如果提供了一个陈旧的响应,他们也必须加入警告。一个缓存可以在特定的情况下提供一个陈旧的响应,大部分情况下是如果缓存无法连接到原始服务器同时客户端声明它可以接受一个陈旧的响应。

如果一个缓存收到了针对一个陈旧页面的请求,它发送一个验证请求询问原始服务器页面是否已经更改。最常见的验证工具便是最后的更新时间。如果在一秒钟内存储了两次更改,Last-Modified将会不正确。因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。

最简便的协助缓存的方法是保持你的HTTP服务器上的时间精确且总是发送Date和Last-Modified头。

另外,要成为一个真正的缓存友好的站长,还要在你的页面中加入缓存头。

可用的缓存头

Expires头是最快捷最方便的解决方案。这个头声明了页面被认为不再可被缓存的时间,在这之后,任何保存了这个页面副本的缓存都应该联系原始服务器。语法是:

Expires: <date in RFC 1123 format>

例如:

Expires: Sun, 10 Feb 2002 16:00:00 GMT

若要标记一个响应为已经“已经过期”或者“不可缓存”,头则应该设置为发送响应的时间。若要标记一个响应为“永不过期”,则应该将头设置为未来的一年。

另一个头是Cache-Control。Cache-Control包括了这些元素:指明页面元素最大时限,他应该如何被缓存的,他如何被转换到另一个不同的媒介,以及他如何被存放在持久媒介中的。

本文使用Apache为例,设置头并在例子中详细讨论Cache-Control头。

在Apache中设置缓存头

#主要的方法:Expires头

要使用Expires头,你需要运行在Apache 1.2或者更新的版本上,同时要启用 mod_expires 模块。去掉httpd.conf文件在“Dynamic Object Support”一节中的 expires_module 一行上的注释,然后重新编译Apache。

#
# Dynamic Shared Object (DSO) Support
#

# LoadModule cern_meta_module /usr/lib/apache/1.3/mod_cern_meta.so
LoadModule expires_module /usr/lib/apache/1.3/mod_expires.so

(如果你运行的是Apache 1.3或更新的版本,同时它已经配置为运行时加载模块,你可以编辑httpd.conf然后重新启动Apache而无需重新编译。)

mod_expires 基于三条指令来计算Expires头。这些指令可以应用于文档范围同时也可以在任何以下范围内使用:“server config”、“virutal host”、“directory”、或者“.htaccess”。

Expires指令有两种语法。其中一个有点难以阅读;它要你计算到失效为止用的秒数。幸运的是,这个模块同样可以读取一个更加人性化的语法。本文将解释较为可读的语法。

要用到的指令是:

ExpiresActive on|off
ExpiresDefault "<base> [plus] {<num>  <type>}*"
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"

base 可以是以下其中之一:

  • access

  • now (等同于“access”)

  • modification

num 是一个整数值,单位是 type :

  • years

  • months

  • weeks

  • days

  • hours

  • minutes

  • seconds

如果你准备对一个服务器、虚拟主机或者是目录使用Expires指令,编辑 httpd.conf 文件并在所需的范围内加入以下指令。

<Directory /whichever/directory/here>
    # 包括任何其他你想要加入这一节的东西
    ExpiresActive on
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType text/html "modification plus 2 days"
    # ExpiresDefault "now plus 0 seconds"
    ExpiresDefault "now plus 1 month"
</Directory>

如果你要在 .htaccess 文件中使用Expires头,那么你要先编辑httpd.conf 设置相应的目录的AllowOverride。Apache只会读取设置了“Indexes”覆盖的目录中的 .htaccess 。

# 针对使用.htaccess的目录,允许Indexes覆盖
<Directory /whichever/directory/here>
    # 包括任何其他你想要加入这一节的东西
    AllowOverride Indexes
</Directory>

在相应目录里的 .htaccess 文件中加入Expires指令。站长可以编辑 .htaccess 文件而无需修改httpd.conf。

“.htaccess”方法的主要问题是Indexes覆盖,这样.htaccess 文件将给予站长更多的配置选项而非仅仅Expires头。这也许并不是系统管理员所期望的。

#候选方法:Cache-Control 头

mod_cern_meta 允许文件级的控制,同时它也可以使用Cache-Control头(或任何其他头)。响应头是放在原始目录的子目录中,根据原始文件名所命名的一个文件。

去掉cern_meta_module 一行的注释并重新编译,和上一节中对expires_module 的一样。

在httpd.conf 文件中,打开MetaFiles on,将 MetaDirectory 设置为子目录名,同时把MetaSuffix设为头的文件的后缀名。

MetaFiles on
MetaDirectory .web
MetaSuffix .meta

使用这些值的话,文件 /var/www/www.example.org/index.html 将会以 /var/www/www.example.org/.web/index.html.meta. 为元文件。

任何有效的HTTP头都可以放在这些文件中。这提供了另一种使用Expires头的方式,同时它可以加入Cache-Control头。相应的Cache-Control头如下:

Cache-Control : max-age = [delta-seconds]

修改失效机制,将覆盖Expires头。Max-age隐含了Canche-Control: public。

Cache-Control : public

表示对象可以被存在缓存中。这是默认值。

Cache-Control : private

Cache-Control : private = [field-name]

表示对象(或指定字段)不能被保存在一个共享的缓存中同时是针对一个单独的用户的。它可以被保存在一个私有的缓存中。

Cache-Control : no-cache

Cache-Control : no-cache = [field-name]

表示对象(或者指定字段)可以被缓存,但不能直接给客户除非经过原始服务器的重新验证。

Cache-Control : no-store

表示条目不能存储在持久的存储媒介中,同时应该尽可能快地从非未定存储媒介中删除。

Cache-Control : no-transform

代理可以将数据从一个存储系统中转换到另外一个。这个指令表示(大多数)响应不能被转换。(RFC允许某些字段的转换,即使存在这个头)

Cache-Control : must-revalidate

Cache-Control : proxy-revalidate

强制代理重新验证该页面即使客户可以接受一个陈旧的响应。请在使用这些头之前阅读RFC,关于他们的使用有一些限制。

警告

  • HTTP/1.0有一个很小的缓存控制机制,仅能理解Pragma: no-cache头。使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。

  • 任何一个Cache-Control指令都不能保证隐私性或者数据的安全性。“private”和“no-store”指令可以为隐私性和安全性方面提供一些帮助,但是他们并不能用于替代身份验证和加密。

  • 本文不能代替RFC。如果你要实现Cache-Control头,请阅读RFC来获取每个头的含义和限制的详细描述。

#最后的话

缓存是Internet的现实问题同时它能让带宽的使用更加有效。你的客户也许是通过一个缓存来浏览你的页面的,有时候还会用多个缓存。给你的页面加上缓存头可以保护你的页面内容也可以让你的客户节省他们的带宽。

#进一步阅读

Jennifer Vesperman 是《Essential CVS》一书的作者。她为O’Reilly Network、Linux Documentation Project撰稿,有时也为Linux.com。

Posted in Web?? | No Comments »