轉載自:http://blog.csdn.net/radic_feng/article/details/6798378
關鍵字:頁面重定向(跳轉,page redirection)、實現方式
寫完標題,我突然想到了孔乙己,魯迅先生嘲笑他以知道茴香豆的茴字有四種寫法而感到自豪。不過我想我和孔乙己還是不同的,因為茴香豆的茴字會寫一種即可,但本文總結的四種頁面重定向的方式應用的場景不盡相同,產生的頁面效果也不同。是有必要加以理解並選擇合適的方式處理不同的場景的。
四種方式:
- 在Server端sendRedirect
- 在Server端使用jsp或RequestDispatcher進行forward
- 在Browser端使用Javascript進行重定向
- 在Browser端使用html標簽進行重定向
以下是對四種方式進行的詳解。
在Server端sendRedirect
示例代碼
- //HttpServletResponse response
- response.sendRedirect("some url");
特點
1. 執行該語句后server會發送一個沒有body的http response。狀態碼(Status Code)為302,在response header中有Location屬性,值為:some url。瀏覽器接到該response后會自動讀取Location的信息,並向指向的URL發出請求,所以你可以在地址欄看到some url了。
值得一提的是,如果第一個請求為Post請求時,現在很多瀏覽器會在第二個請求中轉換為Get請求,這種處理方式並沒有嚴格遵守HTTP協議。HTTP協議對重定向的狀態碼作了細分,增加了303(第二個請求轉換為Get請求)和307碼(第二個請求和第一個請求方法相同)。Eric Law在他的博文中有更詳細的解釋。
2. 由於瀏覽器發出的第二個請求,因此Location中的some url可以跨域(Cross domain),為任意URL。
3. 由於是兩次獨立的請求,所以兩次請求不能共享request里面的數據。
4. 為訪問目的資源,事實上瀏覽器發出了兩個請求,效率較低。
頁面效果
- 瀏覽器地址欄發生變化;
- 由於第一次請求返回的response body為空,所以頁面不會發生閃爍。
使用場景
- 期望讓用戶知道最終的URL,以便加入書簽(Bookmark);
- 在web.xml的welcome file配置中只能指定一個頁面的Location,可以使用一個簡單的頁面,比如jsp,重定向到期望的servlet;
- 在dispatcher中根據用戶身份重定向到各自的系統。
在Server端使用jsp或RequestDispatcher進行forward
示例代碼
JSP中
- <jsp:forward page={"relativeurl" | "<%= expression %>"} >
- <jsp:param name="parametername" value="{parametervalue | <%= expression %>}" /><%--如果沒有參數可以移除該語句 --%>
- </jsp:forward>
- request.getSession().getServletContext().getRequestDispatcher("Some url").forward(request, response);
特點
1. 在Server內部把請求轉發給另一個資源,處理后把結果返回給瀏覽器,該操作對瀏覽器透明,因此地址欄的URL不會發生變化;
2. 兩個資源共享request里的數據;
3. 轉發到的Some url是本系統內部的資源,不能跨域。
頁面效果
- 瀏覽器地址欄的URL不會發生變化;
- 不會出現頁面閃爍。
使用場景
- 服務器不期望用戶了解服務器內部的資源結構信息;
- 不跨域,以期更高的效率。
在Browser端使用Javascript進行重定向
示例代碼
- <script type="text/javascript">
- window.location="Some URL";
- </script>
1. 瀏覽器已經成功得到所請求的頁面了,瀏覽器在執行JavaScript時將地址欄的URL改變,以致向新的URL發出請求。
頁面效果
- 瀏覽器地址欄的URL發生變化;
- 如果第一次請求得到的頁面不是空白,可以看到頁面的閃爍。
使用場景
- 有的框架,比如Apache Tiles,不支持response.sendRedirect,只好用其他的辦法了。。。
在Browser端使用html標簽進行重定向
示例代碼- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- <html>
- <head>
- <title>Welcome to Radic's Blog</title>
- <meta http equiv="refresh" content="0;url=<c:url value="/authenticate.html"/>" />
- </head>
- <body>Redirecting...</body>
- </html>
0表示頁面被加載后發生跳轉的時間,以毫秒為單位,0毫秒表示立即執行跳轉。后面的url指定跳轉的目標URL。參考該文檔了解更多meta http-equiv的用途。
特點
1. 瀏覽器已經成功得到所請求的頁面了,瀏覽器發現meta http-equiv="refresh"時將地址欄的URL改變,以致向新的URL發出請求。
頁面效果
- 瀏覽器地址欄的URL發生變化;
- 如果第一次請求得到的頁面不是空白,可以看到頁面的閃爍。
- 有人會問,瀏覽器禁用了JavaScript,我又不幸使用了Tile框架,怎么辦呢?那就用這種方式把!