Nginx 重定向
> 重定向是通过 Response 状态 301 和 302 完成的, 301 状态是永久重定向, 在用户浏览器中长期保存, 甚至不经过服务器确认, 这种状态最好少用 > 302 状态称为 Found, 告诉浏览器当前访问的 URL 临时移动到另一个 Location 下了, 浏览器应该重新访问这个 Location. > 另外Nginx有内部重定向, 注意区分
配置基于 location 的虚拟机
现在有一个 JSP 项目 Shop, 启动在 http://127.0.0.1:8080, 项目结构如下:
要求访问 http://abc.com/a/ 下的内容时时转发到该项目, Nginx 配置如下:
首先, 当用户访问 http://abc.com/a 时, 不能直接从 location / 转发到 tomcat, 这会造成根目录错误, 所以先精确匹配该URL, 使用return
功能重定向到 http://abc.com/a/ 或 http://abc.com/a/index.jsp
location = /a {
return http://abc.com/a/index.jsp; # 302重定向
}
响应如下:
$ curl -I abc.com/a
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.14.2
Date: Sat, 27 Apr 2019 06:55:04 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: http://abc.com/a/index.jsp
转发 /a/* 到tomcat:
proxy_intercept_errors on; # 开启代理错误拦截
location /a/ {
proxy_pass http://tomcat/Shop/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
error_page 404 /404; # 404页面, 这是一个内部重定向
}
location = /404 {
try_files /static/err.htm =404; # try_files 依次查询文件, 若无则返回一个指定的状态码
}
这样可以让 Nginx 帮我们完成一些有用的功能, 但事实上 Nginx 还可以做更多, 比如反向代理伪装静态
来看这条语句:
location = /a/index {
proxy_pass http://abc.com/a/index.jsp;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
访问 http://abc.com/a/index, 在本地测试, tomcat 中有日志:
注意, 上游服务器可能会301 302重定向到内网服务器, 如果在test目录下写一个index.jsp, 那么
当用户访问http://abc.com/a/test时, tomcat会返回一个302, 重定向到Location: http://abc.com/Shop/test/,
这时要么开启代理错误拦截, 递归错误页面, 即循环内部重定向 (我暂时不知道怎么实现)
要么修改Response中的Location数据, 使用proxy_redirect
可以重定向报文代理:
proxy_redirect http://$host/Shop/ http://$host/a/;
Nginx + tomcat 配置如下
这些虽然有用, 但是要想发挥更大的威力, 不得不提 rewrite 了.
## Nginx URL重写
> URL重写主要使用正则表达式完成
1 upstream tomcat {
2 server 127.0.0.1:8080;
3 }
4
5 server {
6 listen 80;
7 server_name *.javac.ga;
8
9 root /home/d/www;
10 index index.htm index.html;
11
12 #添加 response header
13 add_header developer "develon";
14 add_header 原始uri "$uri$is_args$args";
15
16 #设置代理 Header
17 proxy_set_header Host $host;
18 proxy_set_header X-Real-IP $remote_addr;
19 proxy_set_header Cookie $http_cookie;
20 proxy_set_header X-Forwarded-For $http_add_x_forwarded_for;
21
22 #错误处理
23 error_page 404 = @404; # 全局404
24 proxy_intercept_errors on; # 开启代理错误拦截
25 fastcgi_intercept_errors on; # cgi错误拦截
26 #recursive_error_pages on; # 递归错误页面
27
28
29 location / {
30 }
31
32 location /demo/ {
33 proxy_pass http://tomcat/HeadFirstJSP/;
00 proxy_cookie_path /HeadFirstJSP /demo;
34
35 if ($uri ~ ".jsp$") {
36 rewrite "^/demo/(.+).jsp$" "/demo/$1" redirect;
37 }
38
39 if ($uri ~ "/([^.]+)$") {
40 rewrite "^/demo/(.+)$" "/HeadFirstJSP/$1.jsp" break;
41 }
42
43 proxy_redirect /HeadFirstJSP /demo;
44 error_page 404 = /demo/static/err?err=$uri;
45 }
46
47 location @404 {
48 root /home/d/www;
49 try_files /err.html =404;
50 }
51 }
52
53 server {
54 listen 80 default;
55 return 444;
56 }
该配置的问题及解决办法:
最简单粗暴的配置: