zoukankan      html  css  js  c++  java
  • nginx*tomcat应用,struts2网站程序redirect时导致请求地址错误的解决方法

    一个使用struts2的网站在登录页面需要进行redirect跳转,大致如下:

    <package name="admin" extends="httl-default" namespace="/admin">
            <action name="login" class="com.zandili.tech.action.manage.LoginAdmin">
                <result name="success" type="httl">/admin/login.httl</result>
                <result name="error" type="redirect">/404</result>
                <result name="loginok" type="redirect">/admin/index.do</result>
            </action>
        </package>

    这是struts2中再简单不过的逻辑了,本地测试一切正常,但经过nginx代理后,这个奇葩问题就出现了。

    我们假定两台tomcat的webapps目录下都有一个app目录是我们网站应用的目录,nginx配置如下:

      upstream app_up {
           server 192.168.0.5:8080;

           server 192.168.0.6:8080;
        }
        server {
                    listen  80;
                    server_name www.zandili.com;

                    location / {
                             rewrite ^(.*)$ /app$1 break;
                             proxy_pass http://app_up;
                             proxy_redirect default;
                             proxy_set_header Host $host;
                             proxy_set_header X-Real-IP $remote_addr;
                             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }

            }

    这样我们访问普通页面如http://www.zandili.com/index.do是没有问题的,nginx代理一切正常。

    登录页面地址http://www.zandili.com/admin/login.do

    提交表单后服务端判断用户登录成功后redirect到http://www.zandili.com/admin/index.do

    这个时候我们用Firefox的firebug查看网络访问,就会发现,转向后的url地址为http://www.zandili.com/app/admin/index.do

    目录中多了一个app目录,太意外了,app是后端tomcat下的目录,竟然在redirect的时候传递到了客户端,这不是我想要的。

    此时更可怕的是如果程序里设置了404错误页,我们多了app目录的访问肯定找不到资源,就会无限重定向到404页面......

    为这个问题苦恼啊,难道要为此放弃redirect不成?

    曾经一度的解决方法是把网站部署到webapps下的ROOT目录,这样就不会多一个目录了(这是在逃避问题)。

    仔细查看firebug提供的信息,发现这是个302重定向,多的这个app目录我只能理解为http://www.zandili.com/admin/login.do在进行redirect的时候,根据绝对路径获取到的是http://192.168.0.5:8080/app/admin/index.do的路径,nginx把这个跳转地址替换域名和端口后传递给客户端成http://www.zandili.com/app/admin/login.do这个地址重新发起请求,就出错了(这也就理解了redirect为什么是客户端转向)。

          查了很多资料,一个字眼就频频出现,“proxy_redirect” ,这个在nginx里到底是什么作用?

          NGINX的proxy_redirect功能比较强大,其作用是对发送给客户端的URL进行修改。

          现在问题就出在发送给客户端的URL没有修改成我们需要的路径,看来这个有利于解决问题。

          我们对nginx里的配置稍加修改

    upstream app_up {
           server 192.168.0.5:8080;

           server 192.168.0.6:8080;
        }
        server {
                    listen  80;
                    server_name www.zandili.com;

                    location / {
                             rewrite ^(.*)$ /app$1 break;
                             proxy_pass http://app_up;
                             proxy_redirect default;#这个可以不要了,留着也没有啥危害
                             proxy_redirect http://www.zandili.com/app  http://$host:$server_port;
                             proxy_set_header Host $host;
                             proxy_set_header X-Real-IP $remote_addr;
                             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    }
            }

    其中的

    proxy_redirect http://www.zandili.com/app  http://$host:$server_port;

    就是把服务端的跳转指令中的url进行修改,我们把app目录给抹掉再返回给客户端,这样就正常了。

    看来还是有必要进一步学习下nginx的知识。

  • 相关阅读:
    【经验】AngularJS
    jquery复选框选择 DoTop
    SQL查询数据库名、表名、列名 DoTop
    C#读取配置文件中的信息 DoTop
    ASP.NET获取工程根目录的方法集合 DoTop
    ASP.NET前台Html.DropDownList的使用 DoTop
    JS的同步和异步加载
    tornado nginx 同源(AccessControlAllowOrigin)错误处理记录
    sql join 的一次小使用
    关于CSS3 animation 属性在ie edge浏览器中不能工作
  • 原文地址:https://www.cnblogs.com/airfey/p/3490197.html
Copyright © 2011-2022 走看看