ngx_http_rewrite_module提供的rewrite指令Syntax: rewrite regex replacement [flag]; Default: — Context: server, location, if
如果请求的URI匹配指定的正则表达式regex,URI会被改变为replacement字符串指定的值。rewrite指令会按照它们在配置文件中出现的顺序依次执行。可以通过使用flag标记,来终止这个指令的进一步处理,如果replacement字符串以http://或https://开头,那么会终止处理,并返回重定向给客户端。
可选的flag参数是下面中的一个:
lastngx_http_rewrite_module指令集,开始搜索匹配改变后的URI location(也就是会在当前server标签中使用改变后的URI重新发起匹配)
breakngx_http_rewrite_module指令集
redirectreplacement字符串不以http://或https://开头时使用
permanent完整的重定向URL是根据请求模式($scheme)和server_name_in_redirect指令、port_in_redirect指令来形成的。
下面是一个例子:
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
但是,如果这些指令被放到了download location中,那么应该使用break标记来替换last标记,否则Nginx会循环执行10次,并返回500错误。
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
如果replacement字符串包含新的请求参数,那么之前的请求参数会被追加到它们的后面。如果不希望把之前的请求参数追加到新的请求参数的后面,那么需要在replacement字符串的结尾放一个问号。
下面是一个例子:
rewrite ^/users/(.*)$ /show?user=$1? last;
如果正则表达式中,包含右花括号(})或分号(;),那么整个正则表达式应该使用单引号或双引号括起来。
server_name指令Syntax: server_name name ...; Default: server_name ""; Context: server
设置虚拟主机的名称。比如:
server {
server_name example.com www.example.com;
}
第一个名字是主server name,可以使用星号(*)来作为server name的第一部分或最后一部分。比如:
server {
server_name example.com *.example.com www.example.*;
}
这些名称被称为通配名称。同时:
server {
server_name .example.com;
}
等价于:
server {
server_name example.com *.example.com;
}
也可以在server_name中使用正则表达式,正则表达式以波浪线(~)开头:
server {
server_name www.example.com ~^www\d+\.example\.com$;
}
正则表达式可以包含分组,捕获的分组可以在后面的其他指令中使用,比如:
server {
server_name ~^(www\.)?(.+)$;
location / {
root /sites/$2;
}
}
server {
server_name _;
location / {
root /sites/default;
}
}
可以通过在正则表达式中包含命名的分组,来创建变量,比如:
server {
server_name ~^(www\.)?(?<domain>.+)$;
location / {
root /sites/$domain;
}
}
server {
server_name _;
location / {
root /sites/default;
}
}
如果将server name设置为$hostname,那么会使用机器的主机名称。
也可以指定一个空的server name:
server {
server_name www.example.com "";
}
它允许该虚拟主机处理不带Host头的请求。
在下面的server段例子中,可以看到奇怪的名称-下划线(_):
server {
listen 80 default_server;
server_name _;
return 444;
}
其实,下划线这个名字没有什么特别的,它仅仅是一个许多无效的server name中的一个代表,与任何真实的server name永远不会相交。其它无效的server name,如“ - ” 和“ !@# ”,也可以使用。
default_server:nginx是通过HTTP请求中的Host头来搜索虚拟主机的,如果找不到,那么nginx就会将请求发送到指定了default_server的虚拟主机来处理。
当使用名称搜索虚拟主机的时候,如果名称匹配多个虚拟主机(比如www.example.com既匹配*.example.com,又匹配~^www.(?<domain>.+)$),那么按照下面的优先级,第一个匹配的虚拟主机会被选择:
*.example.com
mail.*
server_name_in_redirect指令Syntax: server_name_in_redirect on | off; Default: server_name_in_redirect off; Context: http, server, location
用来控制:当Nginx发起重定向的时候,开启或关闭主server name的使用(server_name指令的第一个参数就是主server name)。当关闭的时候,会使用Host请求头中的名称,如果没有Host请求头,那么使用服务器的IP地址。
重定向使用的端口,是有port_in_redirect指令来控制的。
port_in_redirect指令Syntax: port_in_redirect on | off; Default: port_in_redirect on; Context: http, server, location
用来控制:当Nginx发起重定向的时候,开启或关闭指定的端口。
重定向使用的主server name是由server_name_in_redirect指令控制的。
rewrite regex replacement [flag],当replacement字符串以http://或https://开头,那么rewrite会终止处理,并返回重定向给客户端。所以此时不应该使用last和break修饰符。
permanent和redirect修饰符的时候,浏览器地址栏的地址会改变,因为使用这两个修饰符的时候,服务器给浏览器返回重定向(301或302),在Location响应头中包含了重定向URL,最后是由浏览器自动的向重定向URL发起请求。last和break修饰符,表示纯粹的内部重定向,浏览器地址栏地址不会发生变化。
permanent或redirect修饰符的时候,浏览器或其它HTTP客户端向重定向URL发起的请求都是GET请求。
在下面这个例子中,会将所有发送到9091端口的请求,转发给9090端口,通过proxy_pass这种方式解决了:浏览器或其他HTTP客户端向重定向URL发起的都是GET请求这个问题,示例配置文件如下所示:
user root;
worker_processes 4;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 0;
server {
listen 9090;
server_name timd.cn;
location = /rewrite_to{
default_type text/plain;
echo "request method is:$request_method, query string is:$query_string, uri is:$uri.";
}
location = /rewrite_from{
rewrite ^ /rewrite_to last;
}
}
server {
resolver 8.8.8.8;
listen 9091;
server_name timd.cn;
location / {
proxy_pass http://$server_name:9090;
}
}
}