Express 是一個基於Node.js 實現的web框架,其響應HTTP請求的response對象中有兩個響應url跳轉方法res.location() res.redirect(),可以實現301 302重定向
1 res.location()
2 re.redirect()
res.location(path)
設置響應的HTTP Location頭,path可以是一下幾種設置形式:
res.location('/foo/bar') res.location('../foo'); res.location('http://baidu.com') res.location('back')
path參數可以是一個絕對路徑 相對路徑 標准的url或是’back‘.當path是’back‘時,響應的location頭會被設置為當前請求的referer頭,當referer頭不存在時會被設置為’/‘
Express通過Location頭將指定的URL字符串傳遞給瀏覽器,它並不會對指定的字符串進行驗證(除了’back‘外)。而瀏覽器則負責將當前的url重定義到響應頭location中指定的url;
res.redirect([status,]path)
status:{number}表示要設置的HTTP狀態碼
path:{string}要設置到location頭中的URL
重定義到path所指定的URL,重定向時可以同時指定HTTP狀態碼,不指定狀態碼默認是302
與location相比,redirect除了要設置path外,還可以指定一個狀態碼,而path參數則於location完全相同,
使用redirect()
重定向時,可以是幾下幾種設置方式:
res.redirect('/foo/bar'); res.redirect('http://itbilu.com'); res.redirect(301, 'http://itbilu.com'); res.redirect('http://itbilu.com', 301); res.redirect('../login'); // /blog/post/1 -> /blog/login res.redirect('back');
url重定向原理
進行url重定向時,服務器只在響應信息的http信息中設置http狀態碼和location頭信息,
當狀態碼為301
或302
時(301
-永久重定向、302
-臨時重定向),表示資源位置發生了改變,需要進行重定向。
Location
頭信息表示了資源的改變的位置,即:要跳重定向的URL。
location與redirect的比較
Express的response對象,時對Node.js原生對象ServerResponse的擴展,location方法只會設置location頭,而redirect() 除了
可以設置location頭外還可以手動或者自動設置HTTP狀態碼,理論上講兩者都可以實現重定向。
location()
方法
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()
方法
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()
方法后,其后的代碼都不會被執行。
3.3 重定向與不重定向
在使用的過程中,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');