问题描述

项目通过Nginx反向代理后,在通过相对路径跳转页面后,报404错误问题,最后排查出来是端口丢失导致。

输入url: http://192.168.xxx.10:8080/myApp/a.html 可以正常访问到页面
但是在这个页面跳转到 myApp/b.html页面,
实际跳转后url: http://192.168.xxx.10/myApp/b.html 这样就出现无法正常显示页面了
若手工将url改为 http://192.168.xxx.10/myApp/b.html 可以正常访问页面

运行环境

举个栗子:项目名称为myApp 运行端口为8080
内网访问地址(只是个🌰,不能访问的哟):
http://192.168.xxx.10:8080/myApp
外网访问地址
http://test.com/myApp

Nginx 配置如下:

http {
	upstream myApp{
        server 127.0.0.1:8081;
    }
	upstream myApp2{
        server 127.0.0.1:8082;
    }
	
    server {
        listen       8080;
        server_name  localhost;
        charset utf-8;
        
        location /myApp {
            proxy_pass  http://myApp2;
            proxy_buffer_size 64k;
            proxy_buffers   32 32k;
            proxy_busy_buffers_size 128k;
            proxy_set_header Host $host;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_redirect default;
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
        }
        location /myApp2 {
            proxy_pass http://myApp2;
            proxy_buffer_size 64k;
            proxy_buffers   32 32k;
            proxy_busy_buffers_size 128k;
            proxy_set_header Host $host;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_redirect default;
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
        }
    }
}

解决方案

这个问题出现的原因为nginx没有正确的把端口信息传送到后端,没能正确的配置nginx,关键配置如下:

proxy_set_header Host $host:$server_port;

加上这个配置以后,通过IP访问的方式可以正常跳转,若你的服务只是通过ip访问当然可以完美解决了。
若还要提供域名无端口访问那就麻烦了,输入url: http://test.com/myApp/a.html 可以正常访问到页面
但是在这个页面跳转到 myApp/b.html页面,
实际跳转后url: http://test.com:8080/myApp/b.html 这样就出现无法正常显示页面了,因Nginx
配置了$host:$server_port,这样导致所有连接都会加上端口。要处理这个问题需要对ip访问和域名访问进行区分。

Nginx关键代码

        	set $serverPort '';
			if ($host = '192.168.0.10') {
				set $serverPort ':${server_port}';
			}
			proxy_set_header Host $host$serverPort;

Nginx修改后的完整代码:

http {
	upstream myApp{
        server 127.0.0.1:8081;
    }
	upstream myApp2{
        server 127.0.0.1:8082;
    }
	
    server {
        listen       8080;
        server_name  localhost;
        charset utf-8;
        
        location /myApp {
        	set $serverPort '';
			if ($host = '192.168.0.10') {
				set $serverPort ':${server_port}';
			}
            proxy_pass  http://myApp;
            proxy_buffer_size 64k;
            proxy_buffers   32 32k;
            proxy_busy_buffers_size 128k;
            proxy_set_header Host $host$serverPort;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_redirect default;
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
        }
        location /myApp2 {
        	set $serverPort '';
			if ($host = '192.168.0.10') {
				set $serverPort ':${server_port}';
			}
            proxy_pass http://myApp2;
            proxy_buffer_size 64k;
            proxy_buffers   32 32k;
            proxy_busy_buffers_size 128k;
            proxy_set_header Host $host$serverPort;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
            proxy_redirect default;
            proxy_connect_timeout 600s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
        }
    }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐