我们在访问网站的时候,你是否经常会见到 URL 中包含 index.html 字符的?很多大型网站却从来没有显示 index.html 字符,这样重写 URL 可以帮助网站实现干净和整洁的地址结构。
1. 没有伪静态
没有伪静态的网站,例如 12306 网站,当我们访问其官网的时候,地址会被跳转到:
https://www.12306.cn/index/
实际上,你会发现当你访问如下地址时,也能够进入 12306 网站首页:
https://www.12306.cn/index/index.html
实际上这两个地址指向的是同一个文件,服务器只设定了索引文件名是 index.html 使得当你访问目录 URL 时会自动寻找当前的索引页面。但是由于没有伪静态的规则,导致了两个链接都可以指向首页内容。由此带来的一些负面效果就是:对于搜索引擎来说,识别出你的网站首页地址有两个,会存在两条记录到搜索引擎中,影响网站权重(当然 12306 这种官方门户网站不用担心权重问题)。还有一个就是 URL 链接地址的不美观。
2. 常用的伪静态
下面介绍两个常用的伪静态规则。
2.1 目录式的组织结构
如果你的网站目录组织结构式目录式的,即每个目录下都有各自的 index.html:
website/ │ ├── assets/ │ ├── login/index.html ├── about/index.html ├── private/index.html │ └── index.html
那么你完全可以将全部 URL 地址中的 index.html 隐藏:
location / { if ($request_uri ~ "/index.html") { rewrite ^(.*)/ $1/ permanent; } }
2.2 根目录式的组织结构
还有一种就是根目录式的组织结构,如下:
website/ │ ├── assets/ │ ├── login.html ├── about.html ├── private.html └── index.html
这种根目录式的组织结构,很方便实现 <header> 复用而不用考虑相对链接的问题。这种组织结构可以将 .html 隐去:
location / { if ($request_uri ~ ^/(.*)\.html$) { return 302 /$1$args; } try_files $uri $uri.html $uri/ =404; }
2.3 说明
以上两个伪静态使用了 if 指令,让 Nginx 对 $request_uri 这个传入部分使用一个正则表达式,正则表达式检查 URI 链接是否有 index.html 或 .html 扩展名,没有就将 URI 的那部分存储在本地变量 $1 中,这个正则表达式同时会检测链接是否有 index.html 或 .html 的后缀,如果有就删除,最后再存到本地变量$1中并进行 302 跳转,$args 保留参数比如请求。
简单解释下用到的正则:
^
: 表示行首;/
: 逐字匹配字符/
,Nginx 中不需要转义正斜杠;(.*)
: 抓取部分:无限次匹配任何字符;\.
: 匹配字符.
,反斜杠转义;html
: 从字面上匹配字符串html
;$
: 表示行尾;(.)
: 包含了链接的非.html
前半部分,之后用$1
变量引用了,为了方便查找文件,这里又添加了.html
后缀来匹配文件。
代码中的 302
跳转是可以改成 301
的,若如果搜索引擎已经收录了带有 index.html 或 .html 后缀的网页后想要去除的话建议使用 301
跳转。
正则表达式可以在这里查看:https://pudding.nousbuild.com/regular-expression/
Nginx rewrite: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html