前言
html ,js 可以實現頁面跳轉。
jsp , asp, php 也有各自頁面跳轉與重定向的方式。
下文針對js 和jsp 的頁面跳轉實現方式進行一個總結。
html 頁面跳轉方式
可以使用html 的meta 標簽實現頁面的跳轉。
<!--Add by oscar999--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Author" CONTENT="oscar999"> <meta http-equiv="refresh" content="0; URL=http://www.csdn.net"> <script> </script> </HEAD> <BODY> This is Test Page </BODY> </HTML>
這種用法比較常使用在:
新舊系統升級的狀況下, 暫時保留舊系統,通過域名進入時自動轉到新系統中。
JS 頁面跳轉方式
1. 使用window.location = "newurl"
<!--Add by oscar999--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> <META NAME="Author" CONTENT="oscar999"> </HEAD> <BODY> This is Test Page. <script> window.location="http://www.csdn.net"; </script> </BODY> </HTML>
也可以使用 window.location.href = "http://www.csdn.net";
2. 使用 window.navigate
<script> window.navigate("http://www.csdn.net"); </script>
3. window.loction.replace方式實現頁面跳轉
<script language="javascript"> window.location.replace("target.aspx"); </script>
有3個jsp頁面(1.aspx, 2.aspx, 3.aspx),進系統默認的是1.aspx,當我進入2.aspx的時候, 2.aspx里面用window.location.replace("3.aspx");
與用window.location.href ("3.aspx");
從用戶界面來看是沒有什么區別的,但是當3.aspx頁面有一個"返回"按鈕,調用window.history.go(-1); wondow.history.back();方法的時候,一點這個返回按鈕就要返回2.aspx頁面的話,區別就出來了,當用 window.location.replace("3.aspx");連到3.aspx頁面的話,3.aspx頁面中的調用 window.history.go(-1);wondow.history.back();方法是不好用的,會返回到1.aspx。
JSP跳轉方式
JSP 跳轉方式大約有三種:
1. response.sendRedirect(“newurl”);
-- 此語句前不允許有out.flush(),如果有,會有異常:
java.lang.IllegalStateException: Can't sendRedirect() after data has committed to the client.
at com.caucho.server.connection.AbstractHttpResponse.sendRedirect(AbstractHttpResponse.java:558)
--跳轉后瀏覽器地址欄變化
--如果要跳到不同主機下,跳轉后,此語句后面的語句會繼續執行,如同新開了線程,但是對response的操作已經無意義了
如果要跳到相同主機下,此語句后面的語句執行完成后才會跳轉;
2. response.setHeader("Location","newurl");
response.setStatus(302);
response.setHeader("location","newurl");
這種使用方式要結合 setStatus(302), 302 這個狀態碼就是告訴瀏覽器要重定向了。
- 此語句前不允許有out.flush(),如果有,頁面不會跳轉。
- 跳轉后瀏覽器地址欄變化
- 此語句后面的語句執行完成后才會跳轉
3. <jsp:forward page="newurl" />
此語句前不允許有out.flush(),如果有,會有異常:
跳轉后瀏覽器地址欄不變,但是只能跳到當前主機下
此語句后面的語句執行完成后才會跳轉
跳轉后得路徑變為當前路徑,圖片不是絕對路徑將無法顯示
例子:
整個簡單的例子: 兩個文件 a.jsp 和 b.jsp .
<!-- by oscar999 --> <!-- This is a.jsp --> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> Before: This is a.jsp! <br> <% //response.sendRedirect("b.jsp"); //response.setStatus(302); //response.setHeader("location","b.jsp"); %> <jsp:forward page="b.jsp"/> After: This is a.jsp! </body> </html>
對於jsp 而言, 就需要嚼一嚼Redirect 和 forward 的差別了。
就字面意思而已: Redirect 翻譯成重定向, forward翻譯成轉發。
兩者的區別是:
重定向是客戶端行為,轉發是服務器行為
重定向過程:客戶瀏覽器發送http請求——》web服務器接受后發送302狀態碼響應及對應新的location給客戶瀏覽器——》客戶瀏覽器發現是302響應,則自動再發送一個新的http請求,請求url是新的location地址——》服務器根據此請求尋找資源並發送給客戶。在這里location可以重定向到任意URL,既然是瀏覽器重新發出了請求,則就沒有什么request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的路徑,客戶可以觀察到地址的變化的。重定向行為是瀏覽器做了至少兩次的訪問請求的。
轉發過程:客戶瀏覽器發送http請求——》web服務器接受此請求——》調用內部的一個方法在容器內部完成請求處理和轉發動作——》將目標資源發送給客戶;在這里,轉發的路徑必須是同一個web容器下的url,其不能轉向到其他的web路徑上去,中間傳遞的是自己的容器內的request。在客戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感覺不到服務器做了轉發的。轉發行為是瀏覽器只做了一次訪問請求。
|
類別
|
概念
|
共享數據
|
應用
|
|
Redirect
|
URL重新定向:可以是任意的URL
|
不能共享request里面的數據
|
一般用於用戶注銷登錄時返回主頁面和跳轉到其它的網站等等
|
|
Forward
|
頁面的轉發:只能是同一個Web應用程序的其他Web組件
|
轉發頁面和轉發到的頁面可以共性request里面的數據
|
一般用於用戶登錄的時候根據角色轉發到相應的模塊等等
|
有個例子說明兩者的區別很生動:
假設你去辦理某個執照
重定向:你先去了A局,A局的人說:“這個事情不歸我們管,去B局”,然后,你就從A退了出來,自己乘車去了B局。
轉發:你先去了A局,A局看了以后,知道這個事情其實應該B局來管,但是他沒有把你退回來,而是讓你坐一會兒,自己到后面辦公室聯系了B的人,讓他們辦好后,送了過來。
以上基本是在頁面層級進行頁面的跳轉, 進入一個頁面后跳入另一個頁面;
下面從項目和服務端來看看有可能在實際的項目中使用到的狀況:
舊的地址跳轉到新的地址
在系統開發過程中, 新舊系統並存是一種常見的處理方法,新舊系統有着各自獨立的域名地址。 、
當新系統開發完成的時候,就需要把舊地址的域名導到新地址中了。
方法之一 就是進行DNS 修改映射了。
如果系統沒有域名, 只有IP, 或是不想修改DNS 的話, 就可以在舊系統中修改主頁面。最簡單的就是類似:
<TITLE>New System</TITLE> <META name="description" content="New System Forward"> <META name="keywords" content="New System"> <META name="robots" content="index,follow,all"> <meta http-equiv="refresh" content="0; URL=http://newurl">
Tomcat 中的地址設定
Tomcat 默認安裝的狀況下(port:8080), 項目部署在webapps 目錄下。
舉例: 這里的域名myweb ,這里的項目名 myproject ,
本地的訪問地址就是 : http://IP:8080/myproject.
域名映射后地址就是: http://myweb:8080/myproject
1. 如何去除端口?
方法一: 在安裝是設置成 80 端口
方法二: 如果已經安裝完成, 可以修改conf\server.xml 的下面配置
修改成 80 就可以了。
這樣就可以通過以下方式訪問了:
http://myweb/myproject
2. 如何去除項目名稱。
最方便的訪問方式應該就是直接輸入 域名就進入了。
http://myweb
方法一: 修改 conf\server.xml 配置
在host 中添加如下Context 的配置:
方法二: 如果不使用方法一的話, 默認狀況上面的地址, 會進入 webapps\ROOT\index.html 這個文件。
所以使用以上的方法修改這個頁面的跳轉應該就能達到所需要的效果了。
二級域名的重定向
新系統雖然已開發完成, 但是還是想有些舊的模塊功能使用舊的系統。
這樣的話, 訪問新系統的某些url 的時候,重定向到舊的頁面地址中去。
以訪問 http://myweb/old 的方式訪問舊的地址(比如舊的地址就是http://www.csdn.net)
方法一: 增加 filter
步驟一: 新增 Filter 的java 文件, 文件名 UrlRewriteFilter.java, 內容如下
package com.oscar999; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** <description> * * @see * @see * * @version 0.1, 2014-5-29 * @author oscar999 * @since JDK1.5 */ public class UrlRewriteFilter implements Filter{ @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String requestPath = httpRequest.getRequestURI(); if(requestPath.indexOf("/old")>0) { //request.getRequestDispatcher("/redirect.html").forward(request, response); httpResponse.sendRedirect("http://www.csdn.net"); return; } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
步驟二: 在web.xml 中 添加filter 的定義
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>com.oscar999.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/old</url-pattern> </filter-mapping>
說明:
1. 在Java 中,滿足轉向的狀況, 一定要return 。 否則會報 IllegalStateException錯誤
2. 可以比較一下, forward 和 redirect 的使用差別 ?
1) 調用的對象不同(request , response)
2) 使用的場景不同(是否是本項目中的文件)
3) url 的地址的變化
3. 轉向的邏輯的可以通過init-param 配置在filter 的 xml 中
<init-param> <param-name></param-name> <param-value></param-value> </init-param>
在filter 的init方法 中,通過 Enumeration<?> e = filterConfig.getInitParameterNames(); 讀到。
這樣的話, 就可以靈活配置轉向的邏輯了。
方法二: 直接使用 urlwrite 組件
其實上面的方式, 已經有共用的組件可以用了。
組件的介紹地址 :
http://tuckey.org/urlrewrite/
目前最新版的下載地址:
http://urlrewritefilter.googlecode.com/files/urlrewritefilter-4.0.3.jar
也可以到:
下載
有了方法一的介紹, 這個組件的使用就很容易了。
1. 下載jar , 放入項目路徑中
2. 配置 web.xml
<filter> <filter-name>UrlRewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>UrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3. 在web.xml 的同路徑下,添加 urlrewrite.xml 文件, 內容如下:
<?xml version="1.0" encoding="UTF-8"?> <urlrewrite> <rule> <from>/old</from> <to type="redirect">http://www.csdn.net</to> </rule> </urlrewrite>
這里可以配置很多的轉向邏輯,不過有上下層級關系時,也就是既有二級域名又有三級域名的話, 配置起來會有一些問題。
不難理解三級在二級的基礎上又換了一次, 導致url 會不對。
另外, 如果項目使用的是 http://myweb/myproject 這種通過項目名訪問的話,
映射舊的地址可以在 tomcat/webapps 中放入一個舊項目同名的項目,里面沒什么內容,專門用來做重定向。
