网站使用条款的处理

网站使用条款,Terms Of Use,也有简称为网规(以下都简称网规)的。前段时间有个需求,就是在用户访问量很大的页面的一个页面添加网规,当时因为时间问题就直接放在动态页面中了,最近开始考虑优化该页面时,才开始考虑如何优化网规。

我们知道网规有如下特点:① 文本量大② 非常稳定不易变,并且可能③ 出现在多个页面,且有可能会网站下次改版时就使用链接,点击链接才能看到网规。还有一个很重要的特点,就是这东西④ 很重要但是没人愿意看。最为常见的网规出现在注册页面,敢问你是不是从来不看网规就直接划勾了?针对以上 ①② 两个特点,网规适合使用浏览器缓存,这样可以减少网络传输内容,提高页面加载性能。针对以上第 ③ 个特点,网规适合使用独立完成,多个宿主页面可以方便地通用 iframe 加载网规,并且宿主页面和网规样式上互不影响。针对第 ④ 个特点,网规适合延时加载,等到必须要用户看的时候才显示出来,要么以链接的形式出现,感兴趣的用户点击查看;或者放在页面靠近底部的地方,让网规占用首屏实在是浪费。

根据以上对网规的特点分析得知,处理网规最好的办法是:为网规创建一个独立页面,设置好浏览器缓存,如果可能延迟加载。那么怎么处理呢?如果放在静态资源项目(该项目包含 js,css,image 等静态资源)或应用(后端)中,都需要有个发布过程,并且网规页面也会引用静态资源项目中的某些基础样式文件,如果放在静态资源项目中,不好处理被引用样式文件的版本。后来想到公司内部有个 CMS 系统叫做 TMS,它可以创建独立 php 页面。

将网规放进 TMS 系统以后,发现了一个并不奇怪但出于预料的问题,该系统对一些词汇做了限制,比如“性虐待”,后来通过<script>document.write('性' + '虐' + '待');</script>或者使用 php 语法<?php echo '性'.'虐'.'待'; ?>两中方法解决。还有一个预料之内的问题,就是如何设置浏览器缓存,最开始以为 TMS 系统应该对此有一套处理方法的,但是后来通过想 TMS 负责人咨询才发现没有,需要手动写 php 代码。好吧,那么我就写 php 代码吧。

1
2
3
4
5
6
7
8
9
<?php
$etag = 'v1';
if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag){
header('Etag:'.$etag, true, 304);
exit;
}else{
header('Etag:'.$etag);
}
?>

在以上代码中,我们使用 Etag/If-None-Match 这对响应头/请求头来做缓存处理,在文档没有变化的情况下,设置 HTTP Code 304,告诉浏览器使用缓存,而不用每次都给用户发一次网规文档。一旦网规文档有任何修改,都必须修改$etag变量的值,否则客户浏览器仍然使用缓存看不到最新网规。不过呢,虽然减少了响应内容,但是每次还是需要一个完整的 HTTP 请求和响应(虽然该响应只有 header,没有 body)。所以啊,我们还需要一个很常用的响应头Cache-Control: max-age=86400来告诉浏览器我给你的文档很新很稳定,在以后的这一天内你都不用再来找我了。Cache-Control是 HTTP1.1 规范中的,为了兼容性,可以使用Expires响应头作为 fallback 方案。由于Expires响应头使用的绝对时间,用来告诉浏览器我给你的文档有效期是某某时候,在那时之前你都不用来找我了。所以如果用户设备日期时间有较大偏差的话,Expires可能会失效。Cache-Control响应头使用相对时间,就不会这个问题,这也是为什么在 HTTP1.1 中增加了Cache-Control响应头的原因之一。废话不多说,上代码。

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$etag = 'v1';
$maxAge = 3600 * 24; // 86400s, 1 day
if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag){
header('Etag:'.$etag, true, 304);
exit;
}else{
header('Etag:'.$etag);
header('Cache-Control: max-age=' . $maxAge);
header('Expires: ' .gmdate('D, d M Y H:i:s', time()+$maxAge). ' GMT');
}
?>

最后一点,如果可能,延迟加载网规文档。这点很简单,就不多讲了。

至此,我们就完成了针对网规的优化:为网规创建一个独立页面,设置好浏览器缓存,如果可能延迟加载。