forward和redirect的區別

1.從地址欄顯示來講
forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪裏來的,因此它的地址欄仍是原來的地址.
redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址.因此地址欄顯示的是新的URL.
2.從數據共享來講
forward:轉發頁面和轉發到的頁面能夠共享request裏面的數據.
redirect:不能共享數據.
3.從運用地方來講
forward:通常用於用戶登錄的時候,根據角色轉發到相應的模塊.
redirect:通常用於用戶註銷登錄時返回主頁面和跳轉到其它的網站等.
4.從效率來講
forward:高.
redirect:低.
本質區別java

解釋一  web

一句話,轉發是服務器行爲,重定向是客戶端行爲。爲何這樣說呢,這就要看兩個動做的工做流程:瀏覽器

轉發過程:客戶瀏覽器發送http請求----》web服務器接受此請求--》調用內部的一個方法在容器內部完成請求處理和轉發動做----》將目標資源 發送給客戶;在這裏,轉發的路徑必須是同一個web容器下的url,其不能轉向到其餘的web路徑上去,中間傳遞的是本身的容器內的request。在客 戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感受不到服務器作了轉發的。轉發行爲是瀏覽器只作了一次訪問請求。服務器

重定向過程:客戶瀏覽器發送http請求----》web服務器接受後發送302狀態碼響應及對應新的location給客戶瀏覽器--》客戶瀏覽器發現 是302響應,則自動再發送一個新的http請求,請求url是新的location地址----》服務器根據此請求尋找資源併發送給客戶。在這裏 location能夠重定向到任意URL,既然是瀏覽器從新發出了請求,則就沒有什麼request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的 路徑,客戶能夠觀察到地址的變化的。重定向行爲是瀏覽器作了至少兩次的訪問請求的。併發

解釋二
重定向,實際上是兩次request,
第一次,客戶端request A,服務器響應,並response回來,告訴瀏覽器,你應該去B。這個時候IE能夠看到地址變了,並且歷史的回退按鈕也亮了。重定向能夠訪問本身web應用之外的資源。在重定向的過程當中,傳輸的信息會被丟失。post


請求轉發是服務器內部把對一個request/response的處理權,移交給另一個
對於客戶端而言,它只知道本身最先請求的那個A,而不知道中間的B,甚至C、D。 傳輸的信息不會丟失。網站


解釋三this

假設你去辦理某個執照,url

重定向:你先去了A局,A局的人說:「這個事情不歸咱們管,去B局」,而後,你就從A退了出來,本身乘車去了B局。spa

轉發:你先去了A局,A局看了之後,知道這個事情其實應該B局來管,可是他沒有把你退回來,而是讓你坐一下子,本身到後面辦公室聯繫了B的人,讓他們辦好後,送了過來。

3、請求重定向與請求轉發的比較

儘管HttpServletResponse.sendRedirect方法和RequestDispatcher.forward方法均可以讓瀏覽器獲 得另一個URL所指向的資源,但二者的內部運行機制有着很大的區別。下面是HttpServletResponse.sendRedirect方法實現 的請求重定向與RequestDispatcher.forward方法實現的請求轉發的總結比較:

(1)RequestDispatcher.forward方法只能將請求轉發給同一個WEB應用中的組件;而 HttpServletResponse.sendRedirect 方法不只能夠重定向到當前應用程序中的其餘資源,還能夠重定向到同一個站點上的其餘應用程序中的資源,甚至是使用絕對URL重定向到其餘站點的資源。若是 傳遞給HttpServletResponse.sendRedirect 方法的相對URL以「/」開頭,它是相對於整個WEB站點的根目錄;若是建立RequestDispatcher對象時指定的相對URL以「/」開頭,它 是相對於當前WEB應用程序的根目錄。

(2)調用HttpServletResponse.sendRedirect方法重定向的訪問過程結束後,瀏覽器地址欄中顯示的URL會發生改變,由初 始的URL地址變成重定向的目標URL;而調用RequestDispatcher.forward 方法的請求轉發過程結束後,瀏覽器地址欄保持初始的URL地址不變。

(3)HttpServletResponse.sendRedirect方法對瀏覽器的請求直接做出響應,響應的結果就是告訴瀏覽器去從新發出對另一 個URL的 訪問請求,這個過程比如有個綽號叫「瀏覽器」的人寫信找張三借錢,張三回信說沒有錢,讓「瀏覽器」去找李四借,並將李四如今的通訊地址告訴給了「瀏覽 器」。因而,「瀏覽器」又按張三提供通訊地址給李四寫信借錢,李四收到信後就把錢匯給了「瀏覽器」。可見,「瀏覽器」一共發出了兩封信和收到了兩次回覆, 「瀏覽器」也知道他借到的錢出自李四之手。RequestDispatcher.forward方 法在服務器端內部將請求轉發給另一個資源,瀏覽器只知道發出了請求並獲得了響應結果,並不知道在服務器程序內部發生了轉發行爲。這個過程比如綽號叫「瀏 覽器」的人寫信找張三借錢,張三沒有錢,因而張三找李四借了一些錢,甚至還能夠加上本身的一些錢,而後再將這些錢匯給了「瀏覽器」。可見,「瀏覽器」只發 出了一封信和收到了一次回覆,他只知道從張三那裏借到了錢,並不知道有一部分錢出自李四之手。

(4)RequestDispatcher.forward方法的調用者與被調用者之間共享相同的request對象和response對象,它們屬於同 一個訪問請求和響應過程;而HttpServletResponse.sendRedirect方法調用者與被調用者使用各自的request對象和 response對象,它們屬於兩個獨立的訪問請求和響應過程。對於同一個WEB應用程序的內部資源之間的跳轉,特別是跳轉以前要對請求進行一些前期預處 理,並要使用HttpServletRequest.setAttribute方法傳遞預處理結果,那就應該使用 RequestDispatcher.forward方法。不一樣WEB應用程序之間的重定向,特別是要重定向到另一個WEB站點上的資源的狀況,都應該 使用HttpServletResponse.sendRedirect方法。

(5)不管是RequestDispatcher.forward方法,仍是HttpServletResponse.sendRedirect方法,在調用它們以前,都不能有內容已經被實際輸出到了客戶端。若是緩衝區中已經有了一些內容,這些內容將被從緩衝區中清除。

zend framework 中的應用

控制這種分發過程的動做控制器方法是_forward()
;在任意的pre/postDispatch()
或者動做中調用該方法,並傳入動做、控制器、模塊、以及可選的附加參數,就能夠進入新的動做。

三種請求轉發得方式

public function fooAction() {

// forward to another action in the current controller and module:
$this->_forward('bar', null, null, array('baz' => 'bogus'));
}

public function barAction() {

// forward to an action in another controller:
// FooController::bazAction(),
// in the current module:
$this->_forward('baz', 'foo', null, array('baz' => 'bogus'));
}

public function bazAction() {

// forward to an action in another controller in another module,
// Foo_BarController::bazAction():
$this->_forward('baz', 'bar', 'foo', array('baz' => 'bogus'));
}

頁面跳轉得方法是

$this->_redirect('/login/add');
相關文章
相關標籤/搜索