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的知識。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM