Nginx url重写rewrite

什么是url重写

url 重写是指通过配置 conf 文件,以让网站的 url 中达到某种状态时则定向/跳转到某个规则,比如常见的伪静态、301 重定向、浏览器定向等。

地址重写与地址转发

地址重写

地址重写是为了实现地址的标准化,比如我们可以在地址栏中中输入 www.baidu.com,我们也可以输入 www.baidu.cn 最后都会被重写到 www.baidu.com 上。浏览器的地址栏也会显示 www.baidu.com

地址转发

地址转发它是指在网络数据传输过程中数据分组到达路由器或桥接器后,该设备通过检查分组地址并将数据转发到最近的局域网的过程。

比较

因此地址重写和地址转发有以下不同点:

  1. 地址重写会改变浏览器中的地址,使之变成重写成浏览器最新的地址。而地址转发他是不会改变浏览器的地址的。
  2. 地址重写会产生两次请求,而地址转发只会有一次请求。
  3. 地址转发一般发生在同一站点项目内部,而地址重写且不受限制。
  4. 地址转发的速度比地址重定向快。

为什么要URL重写

URL 重写是指将一个 URL 请求重新写成网站可以处理的另一个 URL 的过程。这样说可能不是很好理解,举个例子来说明一下,在开发中可能经常遇到这样的需求,比如通过浏览器请求的 http://localhost:8080/getUser?id=1,但是需要通过 SEO 优化等等原因,需要把请求的地址重写为 http://localhost:8080/getUser/1 这样的 URL,从而符合需求或者更好的被网站阅读。

当遇到这种请求的时候,就需要使用到 UrlRewrite 重写或者使用一些网关路由,如 SpringCloud 的 Gateway,Zuul,又或者是 Nginx 来实现这个功能。

当然,URL 重写还可以实现协议跳转,用户通过 http 协议请求网站时,将其重新跳转至 https 协议方式。

Nginx Rewrite配置详解

语法

rewrite regex replacement [flag]

参数

参数 描述
regex 正则,perl 兼容正则表达式语句进行规则匹配
replacement 替代内容,将正则匹配的内容替换成 replacement
flag flag 标记,rewrite 支持的 flag 标记

Rewrite flag标记

标记 说明
last 本条规则匹配完成后,继续向下匹配新的 location URI 规则
break 本条规则匹配完成即终止,不再匹配后面的任何规则
redirect 返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
permanent 返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

regex正则表达式说明

字符 描述
\ 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如 “\n” 匹配一个换行符,而 “$” 则匹配 “$”
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或多次。如 “ol*” 能匹配 “o” 及 “ol”、“oll”
+ 匹配前面的字符一次或多次。如 “ol+” 能匹配 “ol” 及 “oll”、“oll”,但不能匹配 “o”
? 匹配前面的字符零次或一次,例如 “do(es)?” 能匹配 “do” 或者 “does”,"?" 等效于 “{0,1}”
. 匹配除 “\n” 之外的任何单个字符,若要匹配包括 “\n” 在内的任意字符,请使用诸如 “[.\n]” 之类的模式。
(pattern) 匹配括号内 pattern 并可以在后面获取对应的匹配,常用 $0…$9 属性获取小括号中的匹配内容,要匹配圆括号字符需要(Content)

上下文

Context: server,location,if

last与break区别

配置

具体配置如下:

[root@web01 conf.d]# cat rewrite.conf server { listen 80; server_name rewrite.haicoder.net; root /code; location ~ ^/break { rewrite ^/break /test/ break; } location ~ ^/last { rewrite ^/last /test/ last; } location /test/ { default_type application/json; return 200 "ok"; } }

break请求

  1. 请求 rewrite.haicoder.net/break
  2. 首先:会去查找本地的 /code/test/index.html;
  3. 如果找到了,则返回 /code/test/index.html 的内容;
  4. 如果没找到该目录则报错 404,如果找到该目录没找到对应的文件则 403

last请求

  1. 请求 rewrite.haicoder.net/last
  2. 首先:会去查找本地的 /code/test/index.html;
  3. 如果找到了,则返回 /code/test/index.html 的内容;
  4. 如果没找到,会对当前 server 重新的发起一次请求,rewrite.haicoder.net/test/
  5. 如果有 location 匹配上,则直接返回该 location 的内容。
  6. 如果也没有 location 匹配,再返回 404;

总结

break 只要匹配到规则,则会去本地配置路径的目录中寻找请求的文件;而 last 只要匹配到规则,会对其所在的 server(… )标签重新发起请求。

所以,在访问 /break 和 /last 请求时,虽然对应的请求目录 /test 都是不存在的,理论上都应该返回 404,但是实际上请求 /last 的时候,是会有后面 location 所匹配到的结果返回的,原因在于此。

redirect与permanent区别

redirect: 每次请求都会询问服务器,如果当服务器不可用时,则会跳转失败。

permanent: 第一次请求会询问,浏览器会记录跳转的地址,第二次则不再询问服务器,直接通过浏览器缓存的地址跳转。

Nginx url rewrite案例

rewrite ^/(.*) http://www.haicoder.net/$1 permanent;

rewrite 为固定关键字,表示开始进行 rewrite 匹配规则。regex 部分是 ^/(.*) ,这是一个正则表达式,匹配完整的域名和后面的路径地址。

replacement 部分是 http://www.haicoder.net/$1 $1,是取自 regex 部分 () 里的内容。匹配成功后跳转到的 URL。

flag 部分 permanent 表示永久 301 重定向标记,即跳转到新的 http://www.haicoder.net/$1 地址上。

Nginx url rewrite配置实例

我们首先,使用 vim 修改 /etc/nginx/conf.d/default.conf 配置,具体命令如下:

vim /etc/nginx/conf.d/default.conf;

现在,我们配置 url 重写规则,具体配置如下:

server { listen 80; server_name www.haicoder.net; rewrite ^/(.*) http://haicoder.net/$1 permanent; } server { listen 80; server_name haicoder.net; location / { root /data/www/www; index index.html index.htm; } error_log logs/error_www.abc.com.log error; access_log logs/access_www.abc.com.log main; }

修改完毕后,我们启动 nginx,具体命令如下:

nginx

现在,我们使用浏览器访问,此时页面如下:

05_nginx url rewrite.png

我们看到,此时,我们输入的是 www.haicoder.net 自动跳转到了 haicoder.net

Nginx url重写总结

url 重写是指通过配置 conf 文件,以让网站的 url 中达到某种状态时则定向/跳转到某个规则,比如常见的伪静态、301 重定向、浏览器定向等。