总结
- redirect:返回302临时重定向,浏览器地址栏会显示跳转后的URL地址,爬虫不会更新URL。
- permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址,爬虫会更新URL。
- break:停止处理后续rewrite指令集,不会跳出location作用域,不再进行重新查找,终止匹配,URL地址不变。
- last:停止处理后续rewrite指令集,跳出location作用域,并开始搜索与更改后的URI相匹配的location,URL地址不变。
访问关系
客户端 Nginx OpenResty
192.168.1.136 --> 192.168.1.134 --> 192.168.1.132
Nginx配置
events {
worker_connections 1024;
}
http {
log_format haha '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'$http_user_agent "x_forwarded_for":$http_x_forwarded_for' '$server_name $upstream_addr $upstream_status $request_time $upstream_response_time';
access_log /var/log/nginx/haha.log haha;
rewrite_log on; #开启记录rewrite日志
error_log /var/log/nginx/rewrite.log notice;
server {
listen 80;
location / {
#当请求中cookie中包含CRIS
if ($http_cookie ~* "(CRIS)") {
echo "result is:$1"; #这里的$1指的是if里匹配到的(CRIS)
#注意这里不要写成/rr/$1,否则重定向的地址会是/rr//CRIS,就无法匹配到/rr/CRIS这个location,因此会再次匹配/这个location,重复50次后返回500 Error。
rewrite ^(.*)$ /rr$1; #这里的$1指的是uri的内容
}
# [^;]+ 表示1个以上不是;的字符串
# ;|$ 表示;或者空格行(linux空格行以$开头)
if ($http_cookie ~* "a=([^;]+)(;|$)") { echo "http_cookie is:$http_cookie";
echo "id is:$1";
echo "other is:$2";
}
}
location /rr/CRIS {
echo "welcome CIRS";
}
}
}
验证
首先匹配到第二个if:$http_cookie ~* "a=([^;]+)(;|$)"
❯ curl 192.168.1.132/CRIS --cookie "a=test;"
http_cookie is:a=test;
id is:test
other is:;
查看rewrite的日志: 先匹配第一个if没命中,然后找第2个if成功命中。
2020/08/29 12:49:08 [notice] 12610#12610: *432 "(CRIS)" does not match "a=test;", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:49:08 [notice] 12610#12610: *432 "a=([^;]+)(;|$)" matches "a=test;", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
发送请求匹配第一个if
❯ curl 192.168.1.132/CRIS --cookie "a=CRIS" -L -i
HTTP/1.1 200 OK
Server: openresty/1.15.8.2
Date: Sat, 29 Aug 2020 11:57:49 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
welcome CIRS
查看rewrite日志 但是这里发现在首先命中了第1个if后,还会接着去匹配第二个if,这里的第2个if也匹配到了,第2个if的内容也会执行,只是因为我们做了rewrite,所以控制台上没有看到第2个if内的输出结果。
2020/08/29 12:51:36 [notice] 12610#12610: *433 "(CRIS)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:51:36 [notice] 12610#12610: *433 "^(.*)$" matches "/CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:51:36 [notice] 12610#12610: *433 rewritten data: "/rr/CRIS", args: "", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:51:36 [notice] 12610#12610: *433 "a=([^;]+)(;|$)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
假如修改rewrite ^(.*)$ /rr$1 last;后面加上last参数,直接跳出该locaiton,第2个if的动作就不会执行了。
❯ curl 192.168.1.132/CRIS --cookie "a=CRIS" -L -i
HTTP/1.1 200 OK
Server: openresty/1.15.8.2
Date: Sat, 29 Aug 2020 11:57:49 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
welcome CIRS
2020/08/29 12:54:39 [notice] 12805#12805: *440 "(CRIS)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:54:39 [notice] 12805#12805: *440 "^(.*)$" matches "/CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:54:39 [notice] 12805#12805: *440 rewritten data: "/rr/CRIS", args: "", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
假如修改rewrite ^(.*)$ /rr$1 break;后面加上break参数,这次请求就在这个location里终结,会接着执行第2个if里的内容。
❯ curl 192.168.1.132/CRIS --cookie "a=CRIS"
result is:/CRIS
2020/08/29 12:56:48 [notice] 12828#12828: *441 "(CRIS)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:56:48 [notice] 12828#12828: *441 "^(.*)$" matches "/CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:56:48 [notice] 12828#12828: *441 rewritten data: "/rr/CRIS", args: "", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
假如修改rewrite ^(.*)$ /rr$1 redirect;后面加上redirect参数,nginx会向客户端返回302临时重定向。并且第二个if也不会执行。改成permanent结果类似,nginx向客户端返回301永久重定向。
❯ curl 192.168.1.132/CRIS --cookie "a=CRIS" -L -i
HTTP/1.1 302 Moved Temporarily
Server: openresty/1.15.8.2
Date: Sat, 29 Aug 2020 04:59:26 GMT
Content-Type: text/html
Content-Length: 151
Location: http://192.168.1.132/rr/CRIS
Connection: keep-alive
HTTP/1.1 200 OK
Server: openresty/1.15.8.2
Date: Sat, 29 Aug 2020 04:59:26 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
welcome CIRS
2020/08/29 12:59:26 [notice] 12852#12852: *447 "(CRIS)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:59:26 [notice] 12852#12852: *447 "^(.*)$" matches "/CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 12:59:26 [notice] 12852#12852: *447 rewritten redirect: "/rr/CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
假如不加rewrite这条语句,会依次匹配第1个if和第2个if,两个if都会执行,最终在控制台上看到的输出是第2个if的输出。
❯ curl 192.168.1.132/CRIS --cookie "a=CRIS" -L -i
HTTP/1.1 200 OK
Server: openresty/1.15.8.2
Date: Sat, 29 Aug 2020 05:02:04 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
http_cookie is:a=CRIS
id is:CRIS
other is:
2020/08/29 13:02:04 [notice] 12931#12931: *449 "(CRIS)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"
2020/08/29 13:02:04 [notice] 12931#12931: *449 "a=([^;]+)(;|$)" matches "a=CRIS", client: 192.168.1.136, server: , request: "GET /CRIS HTTP/1.1", host: "192.168.1.132"