Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nginx
GitHub Repository: nginx/nginx.org
Path: blob/main/xml/cn/docs/http/ngx_http_rewrite_module.xml
1 views
1
<?xml version="1.0"?>
2
3
<!--
4
Copyright (C) Igor Sysoev
5
Copyright (C) Nginx, Inc.
6
-->
7
8
<!DOCTYPE module SYSTEM "../../../../dtd/module.dtd">
9
10
<module name="ngx_http_rewrite_module模块"
11
link="/cn/docs/http/ngx_http_rewrite_module.html"
12
lang="cn"
13
translator="cfsego"
14
rev="2">
15
16
<section id="summary">
17
18
<para>
19
<literal>ngx_http_rewrite_module</literal>模块允许正则替换URI,返回页面重定向,和按条件选择配置。
20
</para>
21
22
<para>
23
<literal>ngx_http_rewrite_module</literal>模块指令按以下顺序处理:
24
<list type="bullet">
25
26
<listitem>
27
处理在<link doc="ngx_http_core_module.xml" id="server"/>级别中定义的模块指令;
28
</listitem>
29
30
<listitem>
31
为请求查找location;
32
</listitem>
33
34
<listitem>
35
处理在选中的<link doc="ngx_http_core_module.xml" id="location"/>中定义的模块指令。如果指令改变了URI,按新的URI查找location。这个循环至多重复<link doc="ngx_http_core_module.xml" id="internal">10次</link>,之后nginx返回错误<http-status code="500" text="Internal Server Error"/>
36
</listitem>
37
38
</list>
39
</para>
40
41
</section>
42
43
44
<section id="directives" name="指令">
45
46
<directive name="break">
47
<syntax/>
48
<default/>
49
<context>server</context>
50
<context>location</context>
51
<context>if</context>
52
53
<para>
54
停止处理当前这一轮的<literal>ngx_http_rewrite_module</literal>指令集。
55
</para>
56
57
<para>
58
举例:
59
<example>
60
if ($slow) {
61
limit_rate 10k;
62
break;
63
}
64
</example>
65
</para>
66
67
</directive>
68
69
70
<directive name="if">
71
<syntax block="yes">(<value>condition</value>)</syntax>
72
<default/>
73
<context>server</context>
74
<context>location</context>
75
76
<para>
77
计算指定的<value>condition</value>的值。如果为真,执行定义在大括号中的rewrite模块指令,并将<literal>if</literal>指令中的配置指定给请求。<literal>if</literal>指令会从上一层配置中继承配置。
78
</para>
79
80
<para>
81
条件可以是下列任意一种:
82
<list type="bullet">
83
84
<listitem>
85
变量名;如果变量值为空或者是以“<literal>0</literal>”开始的字符串,则条件为假;
86
</listitem>
87
88
<listitem>
89
使用“<literal>=</literal>”和“<literal>!=</literal>”运算符比较变量和字符串;
90
</listitem>
91
92
<listitem>
93
使用“<literal>~</literal>”(大小写敏感)和“<literal>~*</literal>”(大小写不敏感)运算符匹配变量和正则表达式。正则表达式可以包含匹配组,匹配结果后续可以使用变量<var>$1</var>..<var>$9</var>引用。如果正则表达式中包含字符“<literal>}</literal>”或者“<literal>;</literal>”,整个表达式应该被包含在单引号或双引号的引用中。
94
</listitem>
95
96
<listitem>
97
使用“<literal>-f</literal>”和“<literal>!-f</literal>”运算符检查文件是否存在;
98
</listitem>
99
100
<listitem>
101
使用“<literal>-d</literal>”和“<literal>!-d</literal>”运算符检查目录是否存在;
102
</listitem>
103
104
<listitem>
105
使用“<literal>-e</literal>”和“<literal>!-e</literal>”运算符检查文件、目录或符号链接是否存在;
106
</listitem>
107
108
<listitem>
109
使用“<literal>-x</literal>”和“<literal>!-x</literal>”运算符检查可执行文件;
110
</listitem>
111
112
</list>
113
</para>
114
115
<para>
116
举例:
117
<example>
118
if ($http_user_agent ~ MSIE) {
119
rewrite ^(.*)$ /msie/$1 break;
120
}
121
122
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
123
set $id $1;
124
}
125
126
if ($request_method = POST) {
127
return 405;
128
}
129
130
if ($slow) {
131
limit_rate 10k;
132
}
133
134
if ($invalid_referer) {
135
return 403;
136
}
137
</example>
138
<note>
139
内嵌变量<var>$invalid_referer</var>的值是通过<link doc="ngx_http_referer_module.xml" id="valid_referers"/>指令设置的。
140
</note>
141
</para>
142
143
</directive>
144
145
146
<directive name="return">
147
<syntax><value>code</value> [<value>text</value>]</syntax>
148
<syntax><value>code</value> <value>URL</value></syntax>
149
<syntax><value>URL</value></syntax>
150
<default/>
151
<context>server</context>
152
<context>location</context>
153
<context>if</context>
154
155
<para>
156
停止处理并返回指定<value>code</value>给客户端。返回非标准的状态码444可以直接关闭连接而不返回响应头。
157
</para>
158
159
<para>
160
从0.8.42版开始,可以在指令中指定重定向的URL(状态码为301、302、303和307),或者指定响应体<value>文本</value>(状态码为其它值)。响应体文本或重定向URL中可以包含变量。作为一种特殊情况,重定向URL可以简化为当前server的本地URI,那么完整的重定向URL将按照请求协议(<var>$scheme</var>)、<link doc="ngx_http_core_module.xml" id="server_name_in_redirect"/>指令和<link doc="ngx_http_core_module.xml" id="port_in_redirect"/>指令的配置进行补全。
161
</para>
162
163
<para>
164
另外,状态码为302的临时重定向使用的<value>URL</value>可以作为指令的唯一参数。该参数应该以“<literal>http://</literal>”、“<literal>https://</literal>”或者“<literal>https://</literal>”开始。<value>URL</value>中可以包含变量。
165
</para>
166
167
<para>
168
<note>
169
0.7.51版本以前只能返回下面状态码:
170
204、400、402 — 406、408、410、411、413、416 和 500 — 504。
171
</note>
172
173
<note>
174
直到1.1.16和1.0.13版,状态码307才被认为是一种重定向。
175
</note>
176
</para>
177
178
</directive>
179
180
181
<directive name="rewrite">
182
<syntax>
183
<value>regex</value>
184
<value>replacement</value>
185
[<value>flag</value>]</syntax>
186
<default/>
187
<context>server</context>
188
<context>location</context>
189
<context>if</context>
190
191
<para>
192
如果指定的正则表达式能匹配URI,此URI将被<value>replacement</value>参数定义的字符串改写。<literal>rewrite</literal>指令按其在配置文件中出现的顺序执行。flag可以终止后续指令的执行。如果replacement的字符串以“<literal>http://</literal>”或“<literal>https://</literal>”开头,nginx将结束执行过程,并返回给客户端一个重定向。
193
</para>
194
195
<para>
196
可选的<value>flag</value>参数可以是其中之一:
197
<list type="tag">
198
199
<tag-name><literal>last</literal></tag-name>
200
<tag-desc>
201
停止执行当前这一轮的<literal>ngx_http_rewrite_module</literal>指令集,然后查找匹配改变后URI的新location;
202
</tag-desc>
203
204
<tag-name><literal>break</literal></tag-name>
205
<tag-desc>
206
停止执行当前这一轮的<literal>ngx_http_rewrite_module</literal>指令集;
207
</tag-desc>
208
209
<tag-name><literal>redirect</literal></tag-name>
210
<tag-desc>
211
在replacement字符串未以“<literal>http://</literal>”或“<literal>https://</literal>”开头时,使用返回状态码为302的临时重定向;
212
</tag-desc>
213
214
<tag-name><literal>permanent</literal></tag-name>
215
<tag-desc>
216
返回状态码为301的永久重定向。
217
</tag-desc>
218
219
</list>
220
完整的重定向URL将按照请求协议(<var>$scheme</var>)、<link doc="ngx_http_core_module.xml" id="server_name_in_redirect"/>指令和<link doc="ngx_http_core_module.xml" id="port_in_redirect"/>指令的配置进行补全。
221
</para>
222
223
<para>
224
举例:
225
<example>
226
server {
227
...
228
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
229
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
230
return 403;
231
...
232
}
233
</example>
234
</para>
235
236
<para>
237
但是当上述指令写在“<literal>/download/</literal>”的location中时,应使用标志<literal>break</literal>代替<literal>last</literal>,否则nginx会重复10轮循环,然后返回错误500:
238
<example>
239
location /download/ {
240
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
241
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
242
return 403;
243
}
244
</example>
245
</para>
246
247
<para>
248
如果<value>replacement</value>字符串包括新的请求参数,以往的请求参数会添加到新参数后面。如果不希望这样,在replacement字符串末尾加一个问号“?”,就可以避免,比如:
249
<example>
250
rewrite ^/users/(.*)$ /show?user=$1? last;
251
</example>
252
</para>
253
254
<para>
255
如果正则表达式中包含字符“<literal>}</literal>”或者“<literal>;</literal>”,整个表达式应该被包含在单引号或双引号的引用中。
256
</para>
257
258
</directive>
259
260
261
<directive name="rewrite_log">
262
<syntax><literal>on</literal> | <literal>off</literal></syntax>
263
<default>off</default>
264
<context>http</context>
265
<context>server</context>
266
<context>location</context>
267
<context>if</context>
268
269
<para>
270
开启或者关闭将<literal>ngx_http_rewrite_module</literal>模块指令的处理日志以<literal>notice</literal>级别记录到错误日志中。
271
</para>
272
273
</directive>
274
275
276
<directive name="set">
277
<syntax><value>variable</value> <value>value</value></syntax>
278
<default/>
279
<context>server</context>
280
<context>location</context>
281
<context>if</context>
282
283
<para>
284
为指定变量<value>variable</value>设置变量值<value>value</value><value>value</value>可以包含文本、变量或者它们的组合。
285
</para>
286
287
</directive>
288
289
290
<directive name="uninitialized_variable_warn">
291
<syntax><literal>on</literal> | <literal>off</literal></syntax>
292
<default>on</default>
293
<context>http</context>
294
<context>server</context>
295
<context>location</context>
296
<context>if</context>
297
298
<para>
299
控制是否记录变量未初始化的警告到日志。
300
</para>
301
302
</directive>
303
304
</section>
305
306
307
<section id="internals" name="内部实现">
308
309
<para>
310
<literal>ngx_http_rewrite_module</literal>模块的指令在解析配置阶段被编译成nginx内部指令。这些内部指令在处理请求时被解释执行。而解释器是一个简单的堆栈机器。
311
</para>
312
313
<para>
314
比如,下面指令
315
<example>
316
location /download/ {
317
if ($forbidden) {
318
return 403;
319
}
320
321
if ($slow) {
322
limit_rate 10k;
323
}
324
325
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
326
}
327
</example>
328
将被翻译成下面这些指令:
329
<example>
330
variable $forbidden
331
check against zero
332
return 403
333
end of code
334
variable $slow
335
check against zero
336
match of regular expression
337
copy "/"
338
copy $1
339
copy "/mp3/"
340
copy $2
341
copy ".mp3"
342
end of regular expression
343
end of code
344
</example>
345
</para>
346
347
<para>
348
请注意没有对应上面的<link doc="ngx_http_core_module.xml" id="limit_rate"/>指令的内部指令,因为这个指令与<literal>ngx_http_rewrite_module</literal>模块无关。nginx会为这个<link id="if"/>块单独创建一个配置,包含<literal>limit_rate</literal>等于10k。如果条件为真,nginx将把这个配置指派给请求。
349
</para>
350
351
<para>
352
指令
353
<example>
354
rewrite ^/(download/.*)/media/(.*)\..*$ /$1/mp3/$2.mp3 break;
355
</example>
356
可以通过将正则表达式中的第一个斜线“/”放入圆括号,来实现节约一个内部指令:
357
<example>
358
rewrite ^(<emphasis>/</emphasis>download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
359
</example>
360
对应的内部指令将会是这样:
361
<example>
362
match of regular expression
363
copy $1
364
copy "/mp3/"
365
copy $2
366
copy ".mp3"
367
end of regular expression
368
end of code
369
</example>
370
</para>
371
372
</section>
373
374
</module>
375
376