阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx配置URL重写

83次阅读
没有评论

共计 4472 个字符,预计需要花费 12 分钟才能阅读完成。

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

rewrite

语法

在配置文件的 server 块中写,如:

server {rewrite 规则 定向路径 重写类型;}
  • 规则:可以是字符串或者正则来表示想匹配的目标 url
  • 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用 $index 来表示正则里的捕获分组
  • 重写类型:
    • last:相当于 Apache 里德 (L) 标记,表示完成 rewrite,浏览器地址栏 URL 地址不变
    • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏 URL 地址不变
    • redirect:返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
    • permanent:返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

简单例子

server {
    # 访问 /last.html 的时候,页面内容重写到 /index.html 中
    rewrite /last.html /index.html last;

    # 访问 /break.html 的时候,页面内容重写到 /index.html 中,并停止后续的匹配
    rewrite /break.html /index.html break;

    # 访问 /redirect.html 的时候,页面直接 302 定向到 /index.html 中
    rewrite /redirect.html /index.html redirect;

    # 访问 /permanent.html 的时候,页面直接 301 定向到 /index.html 中
    rewrite /permanent.html /index.html permanent;

    # 把 /html/*.html => /post/*.html,301 定向
    rewrite ^/html/(.+?).html$ /post/$1.html permanent;

    # 把 /search/key => /search.html?keyword=key
    rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
}

last 和 break 的区别

因为 301 和 302 不能简单的只返回状态码,还必须有重定向的 URL,这就是 return 指令无法返回 301,302 的原因了。这里 last 和 break 区别有点难以理解:

  • last 一般写在 server 和 if 中,而 break 一般使用在 location 中
  • last 不终止重写后的 url 匹配,即新的 url 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配
  • break 和 last 都能组织继续执行后面的 rewrite 指令

location 里一旦返回 break 则直接生效并停止后续的匹配location

server {
    location / {
        rewrite /last/ /q.html last;
        rewrite /break/ /q.html break;
    }

    location = /q.html {return 400;}
}
  • 访问 /last/ 时重写到 /q.html,然后使用新的uri 再匹配,正好匹配到 locatoin = /q.html 然后返回了400
  • 访问 /break 时重写到/q.html,由于返回了break,则直接停止了

if 判断

只是上面的简单重写很多时候满足不了需求,比如需要判断当文件不存在时、当路径包含 xx 时等条件,则需要用到if

语法

if (表达式) {
}
  • 当表达式只是一个变量时,如果值为空或任何以 0 开头的字符串都会当做 false
  • 直接比较变量和内容时,使用 = 或!=
  • ~ 正则表达式匹配,~* 不区分大小写的匹配,!~ 区分大小写的不匹配

一些内置的条件判断:

  • - f 和!- f 用来判断是否存在文件
  • - d 和!- d 用来判断是否存在目录
  • - e 和!- e 用来判断是否存在文件或目录
  • - x 和!- x 用来判断文件是否可执行

内置的全局变量

$args:这个变量等于请求行中的参数,同 $query_string
$content_length:请求头中的 Content-length 字段。$content_type:请求头中的 Content-Type 字段。$document_root:当前请求在 root 指令中指定的值。$host:请求主机头字段,否则为服务器名称。$http_user_agent:客户端 agent 信息
$http_cookie:客户端 cookie 信息
$limit_rate:这个变量可以限制连接速率。$request_method:客户端请求的动作,通常为 GET 或 POST。$remote_addr:客户端的 IP 地址。$remote_port:客户端的端口。$remote_user:已经经过 Auth Basic Module 验证的用户名。$request_filename:当前请求的文件路径,由 root 或 alias 指令与 URI 请求生成。$scheme:HTTP 方法(如 http,https)。$server_protocol:请求使用的协议,通常是 HTTP/1.0 或 HTTP/1.1。$server_addr:服务器地址,在完成一次系统调用后可以确定这个值。$server_name:服务器名称。$server_port:请求到达服务器的端口号。$request_uri:包含请求参数的原始 URI,不包含主机名,如:”/foo/bar.php?arg=baz”。$uri:不带请求参数的当前 URI,$uri 不包含主机名,如”/foo/bar.html”。$document_uri:与 $uri 相同。

如:

访问链接是:http://localhost:88/test1/test2/test.php 
网站路径是:/var/www/html

$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

例子

# 如果文件不存在则返回 400
if (!-f $request_filename) {return 400;}

# 如果 host 不是 xuexb.com,则 301 到 xuexb.com 中
if ($host != "xuexb.com"){rewrite ^/(.*)$ https://xuexb.com/$1 permanent;
}

# 如果请求类型不是 POST 则返回 405
if ($request_method = POST) {return 405;}

# 如果参数中有 a=1 则 301 到指定域名
if ($args ~ a=1) {rewrite ^ http://example.com/ permanent;}

在某种场景下可结合 location 规则来使用,如:

# 访问 /test.html 时
location = /test.html {
    # 默认值为 xiaowu
    set $name xiaowu;

    # 如果参数中有 name=xx 则使用该值
    if ($args ~* name=(\w+?)(&|$)) {set $name $1;}

    # 301
    rewrite ^ /$name.html permanent;
}

上面表示:

  • /test.html => /xiaowu.html
  • /test.html?name=ok => /ok.html?name=ok

location

语法

server 块中使用,如:

server {location 表达式 {}
}

location 表达式类型

  • 如果直接写一个路径,则匹配该路径下的
  • ~ 表示执行一个正则匹配,区分大小写
  • ~* 表示执行一个正则匹配,不区分大小写
  • ^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他 location。
  • = 进行普通字符精确匹配。也就是完全匹配。

优先级

  1. 等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
  2. ^~ 类型表达式。一旦匹配成功,则不再查找其他匹配项。
  3. 正则表达式类型(~ ~*)的优先级次之。如果有多个 location 的正则能匹配的话,则使用正则表达式最长的那个。
  4. 常规字符串匹配类型。按前缀匹配。

例子 – 假地址掩饰真地址

server {# 用 xxoo_admin 来掩饰 admin
    location / {# 使用 break 拿一旦匹配成功则忽略后续 location
        rewrite /xxoo_admin /admin break;
    }

    # 访问真实地址直接报没权限
    location /admin {return 403;
    }
}

下面关于 Nginx 的文章您也可能喜欢,不妨参考下:

Nginx 403 forbidden 的解决办法  http://www.linuxidc.com/Linux/2017-08/146084.htm

CentOS 7 下 Nginx 服务器的安装配置  http://www.linuxidc.com/Linux/2017-04/142986.htm

CentOS 上安装 Nginx 服务器实现虚拟主机和域名重定向  http://www.linuxidc.com/Linux/2017-04/142642.htm

CentOS 6.8 安装 LNMP 环境(Linux+Nginx+MySQL+PHP)http://www.linuxidc.com/Linux/2017-04/142880.htm

Linux 下安装 PHP 环境并配置 Nginx 支持 php-fpm 模块  http://www.linuxidc.com/Linux/2017-05/144333.htm

Nginx 服务的 SSL 认证和 htpasswd 认证  http://www.linuxidc.com/Linux/2017-04/142478.htm

Ubuntu 16.04 上启用加密安全的 Nginx Web 服务器  http://www.linuxidc.com/Linux/2017-07/145522.htm

Linux 中安装配置 Nginx 及参数详解  http://www.linuxidc.com/Linux/2017-05/143853.htm

Nginx 日志过滤 使用 ngx_log_if 不记录特定日志 http://www.linuxidc.com/Linux/2014-07/104686.htm

CentOS 7.2 下 Nginx+PHP+MySQL+Memcache 缓存服务器安装配置  http://www.linuxidc.com/Linux/2017-03/142168.htm

CentOS6.9 编译安装 Nginx1.4.7  http://www.linuxidc.com/Linux/2017-06/144473.htm

Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-10/147767.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计4472字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中