rewrite
指令是 Nginx 中用于重写 URL 的强大工具。它可以将请求的 URL 重写为另一个 URL,从而实现 URL 转发、重定向等功能。下面是一些常见的 rewrite
指令用法和示例。
基本语法
rewrite regex replacement [flag];
- regex:正则表达式,用于匹配请求的 URL。
- replacement:替换后的 URL。
- flag:可选标志,用于控制重写行为。常见的标志有:
-
last
:停止当前的 rewrite 规则集,开始下一个阶段的处理。 -
break
:停止当前的 rewrite 规则集,不再进行后续的 rewrite 处理。 -
redirect
:返回临时重定向(HTTP 302)。 -
permanent
:返回永久重定向(HTTP 301)。
常见用法
1. 内部重写
内部重写是指将请求的 URL 重写为另一个 URL,但不改变客户端看到的 URL。
示例:将 /old-path
重写为 /new-path
server {
listen 80;
server_name example.com;
location /old-path {
rewrite ^/old-path(.*)$ /new-path$1 last;
}
location /new-path {
# 处理新路径的逻辑
}
}
2. 重定向
重定向是指将客户端请求的 URL 重定向到另一个 URL,客户端会看到新的 URL。
示例:将 /old-path
重定向到 /new-path
server {
listen 80;
server_name example.com;
location /old-path {
rewrite ^/old-path(.*)$ /new-path$1 permanent;
}
location /new-path {
# 处理新路径的逻辑
}
}
3. 使用变量
你可以使用捕获组和变量来动态生成重写后的 URL。
示例:将 /blog/post/123
重写为 /article/123
server {
listen 80;
server_name example.com;
location /blog/post/ {
rewrite ^/blog/post/(.*)$ /article/$1 last;
}
location /article/ {
# 处理文章的逻辑
}
}
4. 条件重写
你可以结合 if
指令来实现条件重写。
示例:如果请求的文件不存在,则重写到 /404.html
server {
listen 80;
server_name example.com;
location / {
if (!-e $request_filename) {
rewrite ^ /404.html break;
}
}
location = /404.html {
# 处理 404 页面的逻辑
}
}
注意事项
- 正则表达式:确保正则表达式正确匹配你想要重写的 URL。
- 标志:
-
last
:停止当前的 rewrite 规则集,开始下一个阶段的处理。 -
break
:停止当前的 rewrite 规则集,不再进行后续的 rewrite 处理。 -
redirect
:返回临时重定向(HTTP 302)。 -
permanent
:返回永久重定向(HTTP 301)。
- 性能:频繁的重写操作可能会影响性能,特别是在高并发情况下。尽量简化重写规则,避免不必要的复杂性。
- 测试:在生产环境中应用重写规则之前,建议在测试环境中进行充分的测试,确保规则正确且不会影响正常访问。
示例配置
以下是一个完整的 Nginx 配置示例,展示了多种 rewrite
用法:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
client_max_body_size 10m;
server {
listen 80;
server_name example.com;
# 内部重写
location /old-path {
rewrite ^/old-path(.*)$ /new-path$1 last;
}
location /new-path {
# 处理新路径的逻辑
}
# 重定向
location /redirect-old {
rewrite ^/redirect-old(.*)$ /redirect-new$1 permanent;
}
location /redirect-new {
# 处理新路径的逻辑
}
# 使用变量
location /blog/post/ {
rewrite ^/blog/post/(.*)$ /article/$1 last;
}
location /article/ {
# 处理文章的逻辑
}
# 条件重写
location / {
if (!-e $request_filename) {
rewrite ^ /404.html break;
}
}
location = /404.html {
# 处理 404 页面的逻辑
}
}
}