NginxRewrite

  1. Rewrite基本概述
  2. Rewrite配置语法
  3. Rewrite标记Flag
  4. Rewrite使⽤场景
  5. Rewrite额外补充

Rewrite基本概述

rewrite 主要实现 url 地址重写, 以及重定向.

Rewrite使用场景

  1. URL访问跳转: ⽀持开发设计, ⻚⾯跳转, 兼容性⽀持, 展示效果
  2. SEO优化: 依赖于url路径,以便⽀持搜索引擎录⼊
  3. 维护: 后台维护, 流量转发等
  4. 安全: 伪静态,真实动态⻚⾯进⾏伪装

eg : 当用于输入www.obgnail.com/noexist这个不存在的网址的时候 , 就可以跳转到www.obgnail.com/index.html这个页面

Rewrite配置语法

1
2
3
4
# 匹配regex这个路径 , 修改成replacement这个路径,最后加一个flag
Syntax: rewrite regex replacement [flag];
Default: --
Context: server, location, if
1
2
# 所有请求转发⾄/pages/maintain.html
rewrite ^(.*)$ /pages/maintain.html break;

Rewrite标记Flag

flag 含义
last 停⽌rewrite检测
break 停⽌rewrite检测
redirect 返回302临时重定向, 地址栏会显示跳转后的地址
permanent 返回301永久重定向, 地址栏会显示跳转后的地址

breaklast的区别

  • last会新建⽴⼀个请求, 请求域名+/test

    也就是说 , 当我们访问http://192.168.68.112/last的时候 , 会重新建立一个请求 , 去访问http://192.168.69.112/test

  • break匹配后不会进行匹配, 会查找对应root站点⽬录下包含/test⽬录

    也就是说 , 当我们访问 http://192.168.68.112/break的时候 , 停止匹配 , 直接去寻找 /test/目录

所以下面配置中,http://192.168.68.112/last正常返回,http://192.168.68.112/break访问404

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name localhost;
root /soft/code;
location ~ ^/break {
rewrite ^/break /test/ break;
}
location ~ ^/last{
rewrite ^/last /test/ last;
}
location /test/{
default_type application/json;
return 200 '{"status":"success"}';
}
}

redirect 与 permanent的区别

1
2
3
4
5
6
7
8
server	{
listen 80;
server_name localhost;
root /soft/code;
location ~ ^/bgx {
rewrite ^/bgx http://kt.xuliangwei.com redirect;
}
}
1
2
3
4
5
6
7
8
server	{
listen 80;
server_name localhost;
root /soft/code;
location ~ ^/bgx {
rewrite ^/bgx http://kt.xuliangwei.com permanent;
}
}

两个的区别就是302和301状态码的区别

  • 302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。

    302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。

  • 而301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。

    301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址。

使用301还是302

尽量使用301

什么时候进行301或者302跳转呢?

  • 当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,打个比方说,我有一套房子,但是最近走亲戚去亲戚家住了,过两天我还回来的。
  • 使用301跳转的场景就是之前的网站因为某种原因需要移除掉,然后要到新的地址访问,是永久性的,就比如你的那套房子其实是租的,现在租期到了,你又在另一个地方找到了房子,之前租的房子不住了。

为什么尽量要使用301跳转?——网址劫持

  • 网址A 做一个302 重定向到网址B 时,主机服务器的隐含意思是网址A 随时有可能改主意,重新显示本身的内容或转向其他的地方。
  • 大部分的搜索引擎在大部分情况下,当收到302 重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302 转向时,百分之百的都抓取目标网址B 的话,就不用担心网址URL 劫持了。
  • 问题就在于,有的时候搜索引擎并不能总是抓取目标网址。
  • 比如说,有的时候A 网址很短,但是它做了一个302 重定向到B 网址,而B 网址是一个很长的乱七八糟的URL 网址,甚至还有可能包含一些问号之类的参数。很自然的,A 网址更加用户友好。这时Google 很有可能会仍然显示网址A。这就造成了网址URL劫持的可能性。
  • 也就是说,一个不道德的人在他自己的网址A 做一个302 重定向到你的网址B,出于某种原因, Google 搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B 上的内容,这种情况就叫做网址URL 劫持。你辛辛苦苦所写的内容就这样被别人偷走了。302 重定向所造成的网址URL 劫持现象,已经存在一段时间了。
  • 简单来说就是 : 从网站A(网站比较烂)上做了一个302跳转到网站B(搜索排名很靠前),这时候有时搜索引擎会使用网站B的内容,但却收录了网站A的地址,这样在不知不觉间,网站B在为网站A作贡献,网站A的排名就靠前了。
  • 301跳转对查找引擎是一种对照驯良的跳转编制,也是查找引擎能够遭遇的跳转编制,它告诉查找引擎,这个地址弃用了,永远转向一个新地址,可以转移新域名的权重。而302重定向很容易被搜索引擎误认为是利用多个域名指向同一网站,那么你的网站就会被封掉,罪名是“利用重复的内容来干扰Google搜索结果的网站排名”。

Rewrite使⽤场景

1
2
3
location / {
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html /course/$1/$2/course_$3.html break;
}

这样 , 用户访问192.168.69.112/course-11-22-course_33.html,就会被重定向到192.168.69.112/course/11/22/course_33.html . 这样就完成了深层嵌套的路径变成短路径

也可以这么使用

1
2
3
4
5
location / {
if ($http_user_agent ~* Chrome){
rewrite ^/nginx http://kt.xuliangwei.com/index.html redirect;
}
}

Rewrite额外补充

Rewrite 匹配优先级(由高到低)

  1. 执⾏server块的rewrite指令
  2. 执⾏location匹配
  3. 执⾏选定的location中的rewrite

Rewrite 优雅书写

bad :

1
2
3
4
5
6
7
server {
listen 80;
server_name www.bgx.com bgx.com;
if ($http_host = nginx.org){
rewrite (.*) http://www.bgx.com$1;
}
}

good :

1
2
3
4
5
6
7
8
9
10
# 将bgx.com全部重定向到www.bgx.com
server {
listen 80;
server_name bgx.com;
rewrite ^ http://www.bgx.com$request_uri?;
}
server {
listen 80;
server_name www.bgx.com;
}

nginx中try_files

语法:

  • try_files file …uri
  • try_files file …= code
1
try_files   $uri    $uri/    /index.php?q=$uri&$args;
  • 依次按照顺序检查文件是否存在,返回第一个找到的文件
  • 最后一个参数,用来回退URI且必须存在,否则将会出现内部500错误。
  • 一般最后一个参数使用@fallback进行重定向指定代理或文件

nginx中try_files的的作用一般用户url的美化

1
2
3
4
5
6
7
8
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .*\.(php|php5)?$
{
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
}
  • 当用户请求 http://localhost/example 时,这里的 $uri 就是 /example。

    try_files 会到硬盘里尝试找这个文件。如果存在名为 /$root/example(其中 $root 是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户。

  • 显然,目录中没有叫 example 的文件。然后就看 $uri/,增加了一个 /,也就是看有没有名为 /$root/example/ 的目录

  • 又找不到,就会fallback到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php。

  • 这个请求会被 location ~ .*.(php|php5)?$ { … } catch 住,也就是进入 FastCGI 的处理程序。而具体的 URI 及参数是在 REQUEST_URI 中传递给 FastCGI 和 PHP 程序的,因此不受 URI 变化的影响。

1
2
3
4
5
6
7
8
loaction / {
try_files $uri @apache
}

loaction @apache{
proxy_pass http://127.0.0.1:88
include aproxy.conf
}
  • try_files方法让Ngxin尝试访问后面得$uri链接,并进根据@apache配置进行内部重定向。
  • 当然try_files也可以以错误代码赋值,如try_files /index.php = 404 @apache,则表示当尝试访问得文件返回404时,根据@apache配置项进行重定向。