简介
rewrite能够根据您的条件将传入的URL更改(重写)到不同的URL是任何Web服务器的基本功能。
Nginx重写功能非常强大且灵活。
我们将在nginx重写中解释以下示例:
- Nginx重写示例使用$1,$2,..
- 使用Nginx重写创建控制器文件
- 在位置上下文中重写中断标志
- 添加问号到Nginx重写替换字符串
- 如果是Context和Rewrite Directive
- Nginx重写标志示例
- 捕获Nginx重写错误日志文件中的命中
以下是nginx重写的语法:
rewrite reg-ex replacement [flag];
在上面:
- rewrite指令是ngx_http_rewrite_module模块的一部分。
- reg-ex - 这是您在此处指定的PCRE正则表达式。这将用于匹配传入的请求URI。
- replacement - 如果reqeust URI与reg-ex匹配,那么Nginx将使用此替换字符串相应地更改请求URI
- flag - 这将决定是否需要进一步处理重写指令。在下面的一个例子中详细解释了这一点。
在nginx中,可以在以下三个上下文中的任何一个内指定rewrite指令:server,location,if
1.使用$1,$2,...的Nginx重写示例
以下是Nginx重写指令的示例:
rewrite ^(/data/.*)/html/(\w+)\.?.*$ $1/linux/$2.html last;
例如:
- url/data/www/html/test.php将被重写为url/data/www/linux/test.html
- 在此示例中,当您使用test.php从浏览器调用原始URL时,它将根据上述重写规则进行重写,并将从/data/www/linux/提供test.html页面
在上面的重写规则中:
- $1和$2将从原始URL捕获不会更改的相应字符串
- 替换字符串中的$1将匹配reg-ex中第一个括号()内的任何内容。在我们的例子中,$1是/data/
- 类似地,$2将匹配reg-ex中第二个括号()内的任何内容。所以,$2是(\w+),这是原始网址中/html/之后的任何单词。在我们的例子中,$2是测试
- last - 此标志将确保停止在当前位置或块中搜索重写指令并使用更改的URI(即重写的URI)并查找匹配的任何进一步重写指令的新位置。
-
- $ - 这表示原始URL中的扩展名。请注意,在此处,原始URL的扩展名将被替换后的URL替换为.html。因此,即使您在原始URL中调用.php,它也只会在重写的URL中提供.html文件。
虽然Nginx重写规则与Apache类似,但在如何在Nginx中编写重写规则方面仍存在很多差异。
2.使用Nginx重写创建控制器文件
使用重写,您可以将许多传入的原始URL路由到将为这些请求提供服务的主控制器模板。
以下重写示例解释了这一点。
rewrite ^/linux/(.*)$ /linux.php?www=$1 last;
在上面的示例中,当您调用abcgo.com/linux/centos URL时,它将使用上述规则进行重写,它将使用此重写的URL提供页面:abcgo.com/linux.php?www=centos
如上所示,任何与此处模式匹配的URL(即URL中的/linux/)都将由linux.php提供,但原始传入URL中的最后一部分将用作发行版中的参数的值。 linux.php控制器。
因此,上述重写规则将转换传入的URL,如下所示:
- linux/centos成为linux.php?www=centos
- linux/debian成为linux.php?www=debian
- linux/redhat成为linux.php?www=redhat
- 等等
与前面的示例类似,我们在替换字符串中使用$1来捕获reg-ex中第一个括号()内的任何内容。在这种情况下,这是原始传入URL的最后一部分。
我们还使用此处的最后一个标志来指示nginx停止在当前块中搜索进一步的重写指令,并继续移动到下一个匹配位置以进行进一步搜索。
3.在位置上下文中重写中断标志
在这个例子中,我们将重写条件放在location指令中。
在此示例中,location指令是/data/,它还匹配下面给出的替换字符串中的$1。
location /data/ {
rewrite ^(/data/.*)/html/(\w+)\.?.*$ $1/linux/$2.html break;
return 403;
}
如果你使用上面的“最后”标志会发生这种情况:
- 因此,如果您将“last”作为标志,则在初始重写URL之后,Nginx通常会查找新URL的下一个重写指令。
- 在这种情况下,Nginx将继续重定向到相同的位置数据并继续处理相同的重写规则最多10次,最后它将返回500错误代码。
因为,我们不希望出现上述行为,我们在这里使用了“break”作为标志,它将再次停止处理重写块。
要在位置上下文中有效使用重写指令,您需要了解位置如何工作的详细信息
4.向Nginx重写替换字符串添加问号
如果替换字符串包含新请求参数,则先前的请求参数将附加在它们之后。如果您不想要此行为,请在替换字符串的末尾添加问号,以避免添加它们。
在以下示例中,在替换字符串部分中,末尾没有问号。即$1后无问号
rewrite ^/linux/(.*)$ /linux.php?www=$1 last;
在上面的示例中,当替换字符串包含传入的请求参数时,之前请求的参数将附加在它们之后。
有时候,你可能不希望这种情况发生。在那种情况下,使用?如下所示。
在下面的例子中,在Nginx重写的替换字符串部分中,我们添加了?在末尾。即$1后有一个问号
rewrite ^/linux/(.*)$ /linux.php?www=$1? last;
在上面的示例中,替换字符串包含传入的请求参数,然后不会在它们之后附加前一个请求的参数。
5.如果上下文和重写指令
以下几个示例说明我们可以在if指令中使用重写。
您可以通过使用$scheme,$http_host,$http_user_agent等变量进行条件比较来进行条件重写,如下所示:
if ($scheme="http") {
rewrite ^ https://www.abcgo.com$uri permanent;
}
if ($http_host=abcgo.com) {
rewrite (.*) https://www.abcgo.com$1;
}
if ($http_user_agent=MSIE) {
rewrite ^(.*)$ /pdf/$1 break;
}
请注意,有更好的方法可以实现上述示例的最终结果。上面的例子只是为了表明我们可以在nginx配置文件中的if语句中添加重写指令。
请注意,您还可以在nginx配置文件中将以下两个参数的值设置为on或off:
server_name_in_redirect on
port_in_redirect off
6. Nginx重写标志示例
以下是您可以使用的4种不同的Nginx Rewrite指令标志。
**last:**此标志将停止处理当前集中的重写指令,并将从与更改的URL匹配的新位置开始。
rewrite ^(/data/.*)/html/(\w+)\.?.*$ $1/linux/$2.html last;
**break:**该标志将停止处理当前集合中的重写指令。
rewrite ^(/data/.*)/html/(\w+)\.?.*$ $1/linux/$2.html break;
redirect: 此标志将使用302 HTTP代码执行临时重定向。这主要在替换字符串不是http,或https或$scheme时使用
**permanent:**此标志将使用301 HTTP代码执行永久重定向
rewrite ^ https://www.abcgo.com$uri permanent;
7.捕获错误日志文件中的Nginx重写命中
默认情况下,只要Nginx成功重写,它就不会将其记录在error.log中。
最初在编写复杂的重写规则时,您确实希望确保Nginx根据您的要求进行重写。
为此,您应该启用重写日志,该日志将在nginx使用配置文件中的任何一个重写指令成功重写时随时写入日志条目。
为此,请使用rewrite_log指令并将其设置为on。
将以下两行添加到nginx default.conf中:
error_log /var/log/nginx/error.log notice;
rewrite_log on;
在上面:
- 第一行指示我们要写入重写消息的error_log文件的位置。请注意,重写消息属于类型通知。因此,您必须在此行的末尾添加“note”,如上所示。
- rewrite_log on - 该行允许将ngx_http_rewrite_module模块的所有指令记录到error_log文件中。
完成上述更改后,您将开始看到这样的行,这些行清楚地显示了在转换传入URL时使用了哪些特定的重写规则。这也将在日志条目中显示最终翻译的URL。
[notice] 14385#14385: *1 "^(/data/.*)/html/(\w+)\.?.*$" matches "/data/www/html/test", client: 192.168.199.2, server: localhost, request: "GET /data/www/html/test HTTP/1.1", host: "192.168.199.20"
[notice] 14385#14385: *1 rewritten data: "/data/www/linux/test.html", args: "", client: 192.168.199.2, server: localhost, request: "GET /data/www/html/test HTTP/1.1", host: "192.168.199.20"
在上面:
- 第1行显示两件事1)传入URL 2)重写使用的规则
- 在第1行中,它显示传入的URL(即请求)。在此示例中,请求为:“GET/data/www/html/test”
- 在第1行中,它还显示与此传入请求匹配的Nginx重写规则。在这个例子中,nginx使用的重写规则是:
“^(/data/.*)/geek/(\w+)\.?.*$”
- 在第二行中,它显示了应用重写规则后Nginx使用的重写的翻译URL。在此示例中,翻译的重写URL为:
/data/www/linux/test.html