Express是一個基於Node.js實現的Web框架,其響應HTTP請求的response
對象中有兩個用於URL跳轉方法res.location()
和res.redirect()
,使用它們能夠實現URL的301或302重定向。javascript
res.location(path)
下面列舉了幾種,設置http響應頭Location的方法html
res.location('/foo/bar'); res.location('http://example.com'); res.location('back');
路徑值back具備特殊的意義,這個涉及到請求頭Referer
中指定的URL,若是Referer頭沒有指定,將會設置爲'/'。
java
Express
經過Location
頭將指定的URL字符串傳遞給瀏覽器,它並不會對指定的字符串進行驗證(除'back'
外)。而瀏覽器則負責將當前URL重定義到響應頭Location
中指定的URL。node
其中參數:express
status
:{Number},表示要設置的HTTP狀態碼path
:{String},要設置到Location
頭中的URL使用指定的http狀態碼,重定向到指定的URL,若是不指定http狀態碼,使用默認的狀態碼」302「:」Found「,api
res.redirect('/foo/bar'); res.redirect('http://example.com'); res.redirect(301, 'http://example.com'); res.redirect('../login');
重定向能夠是一個完整的URL,這樣會重定向到一個不一樣的站點上。瀏覽器
res.redirect('http://google.com');
重定向也能夠相對於所在主機的根目錄,例如,若是你的程序運行在:http://example.com/admin/post/new上下面的代碼將會重定向到以下地址:http://example.com/admin服務器
res.redirect('/admin');
重定向也能夠相對於當前的URL,例如:從http://example.com/blog/admin/這個地址(注意反斜槓),下面的代碼將會重定向到地址:http://example.com/blog/admin/post/new
框架
res.redirect('post/new')
在從地址: http://example.com/blog/admin重定向到
postpost/new,若是沒有反斜槓的話將會重定向到:http://example.com/blog/post/new
若是你感受上面的行爲很迷惑,想一想文件目錄和文件的路徑,這會讓你更好理解。
相對路徑的重定向也是容許的,若是你的地址是: http://example.com/admin/post/new,下面的代碼將會重定向到http//example.com/admin/post這個地址:
res.redirect('..');
back重定向,重定向到請求的referer,當沒有referer請求頭的狀況下,默認爲‘/’
res.redirect('back');
進行URL重定向時,服務器只在響應信息的HTTP頭信息中設置了HTTP狀態碼
和Location
頭信息。
當狀態碼爲301
或302
時(301
-永久重定向、302
-臨時重定向),表示資源位置發生了改變,須要進行重定向。
Location
頭信息表示了資源的改變的位置,即:要跳重定向的URL。
location()
與redirect()
的比較Express
的response
對象,是對Node.js原生對象ServerResponse
的擴展。location()
方法只會設置Location
頭,而redirect()
方法除了會設置Location
頭外還可自動或手頭設置HTTP狀態碼
。理論上講二者能夠實現重定向。
location()
方法實現過程大體以下:
res.location = function(url){ var req = this.req; // "back" 是 referrer的別名 if ('back' == url) url = req.get('Referrer') || '/'; // 設置Lcation this.setHeader('Location', url); return this; };
從以上代碼能夠看出,location()
方法本質上是調用了ServerResponse
對象的setHeader()
方法,但並無設置狀態碼。經過location()
設置頭信息後,其後的代碼還會執行。
使用location()
方法實現URL的重定向,還要手動設置HTTP狀態碼
:
res.location('http://itbilu.com');
res.statusCode = 301;
若是須要當即返回響應信息,還要調用end()
方法:
res.location('http://itbilu.com'); res.statusCode = 301; res.end('響應的內容'); // 或 res.location('http://itbilu.com'); res.sent(302);
redirect()
方法實現過程大體以下:
res.redirect = function(url){ var head = 'HEAD' == this.req.method; var status = 302; var body; // 一些處理 …… // 經過 location 方法設置頭信息 this.location(url); // 另外一些處理 …… // 設置狀態並返回響應 this.statusCode = status; this.set('Content-Length', Buffer.byteLength(body)); this.end(head ? null : body); };
從以上代碼能夠看出,
redirect()
方法是對location()
方法的擴展。經過location()
設置Loction
頭後,設置HTTP狀態碼
,最後經過ServerResponse
對象的end()
方法返回響應信息。調用redirect()
方法後,其後的代碼都不會被執行
在使用的過程當中,redirect()
方法大多能重定向成功,而location()
方法則不太肯定,有時能夠成功有時不能成功。這與咱們的用法有關。
上面講過,URL重定向是在瀏覽器端完成的,而URL重定向與HTTP狀態碼
和Location
頭有關。瀏覽器首先會判斷狀態碼,只有當狀態碼是:301
或302
時,纔會根據Location
頭中的URL進行跳轉。
因此,使用location()
設置頭信息,而不設置狀態碼或狀態碼不是301
或302
,並不會發生重定向:
res.location('http://itbilu.com');
res.sent(200);
而使用redirect()
設置的狀態碼不是301
或302
也不會發生跳轉:
res.redirect(200, 'http://itbilu.com');
參考:
一、http://itbilu.com
二、http://www.expressjs.com.cn/4x/api.html#res.location