RewriteBase指令的错误理解

之前错误的认为RewriteBase只会影响RewriteRule指令在匹配url时,是完全匹配还是不包含域名匹配。这种理解不正确,看个例子:

假如我们的服务器目录下有/a/b/目录,对于这个目录,我们使用了Alias指令

Alias /a /root/b
// 即我们访问www.server-name.com/a/index.html会返回/root/b/index.html

这时, 如果我们访问www.server-name.com/a/old.html,且在/root/b下有.htaccess文件,内容如下:

RewriteEngien On

RewriteBase /a

RewriteRule ^old\.html$ new.html

会发生什么?

分析一下:

  1. 因为Alias指令的存在,所以:/a/old.html  =>  /root/b/old.html
  2. 因为 b目录下有.htaccess文件,所以:/root/b/old.html  =>  /root/b/new.html
  3. 这里就体现RewriteBase的功能了,因为设置成/a,所以:/root/b/new.html  =>  /a/new.html。
  4. 最后,因为Alias指令,/a/new.html  =>  /root/b/new.html

关于第三点,回到刚开始我错误的理解,就是RewriteRule在匹配url时,是怎么匹配的?我的理解是以.htaccess文件所在目录为基准的,举个例子:假如.htaccess文件在/a/b/c目录下,那么当我们访问www.sn.com/a/b/c/d/old.html,那么是从/d开始匹配的,即匹配/b/old.html。

所以RewriteBase是目录级重写的基准,即当我们用RewriteRule不是重定向或者代理时,如何寻找新的目录或文件。

apache静态文件缓存的一些配置

在web应用中,合理利用缓存很重要。对于静态文件css/js/image/html等,可以使用http缓存。

每个浏览器都自带了 HTTP 缓存实现功能。您只需要确保每个服务器响应都提供正确的 HTTP 标头指令,以指示浏览器何时可以缓存响应以及可以缓存多久。

一般常用的会用Exprise,Last_Modified等头信息控制缓存。Cache-Control 标头是在 HTTP/1.1 规范中定义的,取代了之前用来定义响应缓存策略的标头(例如 Expires)。所有现代浏览器都支持 Cache-Control,因此,使用它就够了。

  • 每个资源都可通过 Cache-Control HTTP 标头定义其缓存策略
  • Cache-Control 指令控制谁在什么条件下可以缓存响应以及可以缓存多久

具体有一盘文章可以参考,http缓存,这儿就不多细说了。

既然缓存这么重要,那么服务器怎么配置很关键。这儿又有个常见服务器配置文件标准范例,找到你的服务器,参照着配置就行。

从上面来看,主要就两个标志很重要,Cache-Control和Etag,apache如何去配合使用这两个特性呢,假如我的根目录 的所有的css/js/image等静态文件都需要一个月的缓存,而且需要配合Etag的特性去保持更新。

首先看Cache-Control如何设置,在http.conf或者.htaccess(如果允许),加上一点代码:

<IfModule mod_headers.c>
    <File ~ "./(gif|jpg|jpeg|png|css|js)$">
          Header set Cache-Control  "max-age=2592000,public"
    </File>
</IfModule>

意思是说,如果加载了mod_headers这个模块,匹配文件以jpg,css,js等结尾的,在响应头内加上Cache-Control选项,缓存一个月(其实应该按照需求去设置)。用正则匹配的话可以使用FileMatch容器。

先看看不加这段代码。访问一张图片是怎样响应的

可以看到,响应里并没有cache-control,然后我们加上设置,重启,再访问一次看看

已经有了,一个月的缓存时间,很好。

cahce-control已经有了,还剩个Etag,其实apache默认就支持Etag,不用去设置,浏览器也会自动发送If-None-Match头去验证,很多工作都是自动的,但是它也有一些不同的生产方法。

apache支持FileEtag这个命令,官方介绍,它的参数主要有:INode,Size,Mtime,All,None

Inode是指每个文件的在文件系统里的i-node,Mtime指文件上次修改的时间,Size指大小,None就是不在响应里加上Etag标志。All就是FileEtag INode MTime Size

一般不用Inode,因为默认的ETag使用到的Innode会导致相同的文件在分布式服务器上产生的ETag不同。

看上图,我们访问后,产生的Etag : 303f-556eb6039b504,能看出来只使用了两个属性,如果我们想使用All去生成,那么可以:

<Direcrtory doucment_root>
     FileEtag All
</Directory>

重启,在访问一次,

很好发生变化了。变成 “9000000007bd9-303f-556eb6039b504″,显然多了一个。

平常开发中,可能会有不一样的需求,每个文件都可能需要不一样的缓存策略。

杂文一篇,有错望指出。

 

apache配置文件相关总结。

与apache打交道,apache的配置文件应该会接触的比较多,最核心当属http.conf这个文件。这个文件里有很多detectives(命令),一些常用的命令:

1. 命令

DocumentRoot : 根目录,客户端有权限可访问的。配置虚拟主机对应变化。例如:

/usr/local/apache/htdocs

ServerRoot : 软件的安装目录。例如

ServerRoot /usr/local/apache

LoadModule : 动态加载其他的模块,语法格式为LoadModule 模块 模块文件名称,模块文件一般位于ServerRoot指定目录下的modules目录中,例如:

LoadModule actions_module modules/mod_actions.so

LoadFile: 类似楼上,也可以加载模块文件,例如:

LoadFile "libexec/libxmlparse.so" 

Include: 加载其他一些配置文件,可以使用shell-style通配符*,例如

 Include /usr/local/apache/conf/*.conf

如果加载的文件存在找不到的情况,该命令会出错,可以使用升级版命令,IncludeOptional。该命令会忽略找不到的错误。

Order: 用于设置指定目录的访问权限。不过2.4后好像被Require取代了

Require: 类似Order命令。设置访问权限,例如:

Require all denied/granted,代表全部拒绝/允许。

Require user/group userid/group-name [user-id]/[group-name] , 允许通过用户id或组名来控制

Require ip *.*.*.*,允许ip。空格隔多个

Options: 设置指定目录的一些选项,有MultiView(多语言相关),Indexed(当没有指定index.*,列出目录树),FollowSysLinks(允许目录下通过链接文件链接到目录外的文件或目录),ExecCGI(允许执行CGI脚本)等等

AllowOverride: 允许指定的目录下,使用.htaccess这个文件。必须加载了mod_rewrite模块。

 2. 一些容器命令

<Directory path></Directory>:用来设置指定的目录,子目录和文件。文件路径最好用引号包起来,因为防止有空格,而一个空格代表一个参数的结束。也可以用正则表达式来表示,但是必须前面加上~符号,或者使用DirectoryMatch容器命令。
<IfModule module_name></IfModule>:当指定的模块被加载了,才会执行容器里的命令。例如:

<IfModule mime_magic_module>
    MIMEMagicFile "conf/magic"
</IfModule>

 <Files file></Files>: 类似Directory,用来对指定文件操作。

 <FilesMatch file_reg></FilesMatch>: 类似DirectoryMatch,可以使用正则表达式。也可以用~符号代替。

 <Location url></Location>: 对指定的url操作。

<LocationMatch url_reg></Location>,同上。

 

相关参考:

http://httpd.apache.org/docs/2.4/mod/core.html#directory

http://www.bianceng.cn/Servers/web/201312/39092_4.htm