2015-10-19 132 views
8

我使用快遞4.13.3(最新)和下面的代碼:爲什麼POST重定向到GET並且PUT重定向到PUT?

var express = require('express') 

var app = express() 

app.get('/test', function (req, res, next) { 
    res.send('hello!') 
}) 

app.post('/test', function (req, res, next) { 
    res.redirect('/test') 
}) 

app.put('/test', function (req, res, next) { 
    res.redirect('/test') 
}) 

app.listen(5001) 

// GET /test -> 'hello!' 
// POST /test -> 'hello!' 
// PUT /test -> ERR_TOO_MANY_REDIRECTS 

POST重定向到GET但PUT重定向到PUT。是否有可能使PUT重定向到GET(與POST相同)?

回答

7

在細節潛水前,下面是你如何能夠解決這個問題的一種方法:

app.put('/test', function(req, res, next) { 
    res.redirect(303, '/test') // Notice the 303 parameter 
}) 

默認情況下,Express使用HTTP代碼302重定向。按照HTTP specification,這樣可以防止被重定向爲POST/PUT請求POST/PUT請求,並解釋了在代碼中觀察到:

如果接收到響應的302個狀態碼比 其他的請求GET或HEAD,用戶代理絕不能自動重定向 請求,除非用戶可以確認,因爲這可能會改變發出請求的條件。

在另一方面,如果使用一個303重定向,則POST/PUT請求允許被重定向爲POST/PUT請求中this great SO answer解釋:

303:重定向爲未定義原因。通常情況下,'操作已完成 ,在其他地方繼續。這個資源的後續請求 的客戶端不應該使用新的URI。對於POST/PUT/DELETE請求,客戶端應該遵循 重定向。

+0

但爲什麼表達式重定向PUT - > PUT和POST - > GET? POST/PUT應該重定向到「平等」的權利?看起來快遞自動使用303用於POST,302用於PUT? – user606521

+2

@ user606521最新的HTTP 1.1規範特別允許302重定向將POST更改爲GET。 (請參閱我的答案中RFC的相關引用。)除了特定的POST到GET更改外,規範不允許進行任何其他轉換,因此PUT仍然是PUT。這是歷史原因;即瀏覽器實現了原始規格錯誤,並且規範發生變化以允許此錯誤。 – apsillers

1

put的方式是正確的,你將請求重定向到另一個位置,但http方法是一樣的。這就是爲什麼它試圖再次訪問put(你不改變HTTP方法。)

爲什麼post被重定向到get

這裏是answer

8

首先,讓我們明白了什麼res.redirect does

res.redirect([狀態]路徑)

重定向到從指定的路徑得到的URL,以指定的HTTP狀態代碼狀態。如果您不指定狀態,則狀態代碼默認爲「302」找到「。

如果我們看一下HTTP 1.1 spec for a 302 response,我們看到

注:由於歷史原因,用戶代理可以改變從POST請求 方法得到的後續請求。如果這種 行爲是不希望的,則可以使用307(臨時重定向)狀態代碼 代替。

307請求將在所有情況下保留HTTP動詞,但那不是你想要的。你想讓動詞改變爲GET。在這種情況下,你想有一個303

303查看其它

303(見其他)狀態代碼表示服務器是 重定向用戶代理到不同的資源,通過指示位置標題字段中的 URI,旨在提供對原始請求的間接響應 。用戶代理可以執行 作爲針對該URI的檢索請求(GET或HEAD請求,如果 使用HTTP),它可能也會被重定向,並將最終的 結果作爲原始請求的答案。

303響應將提示客戶端(提供它瞭解HTTP 1.1)在指定的資源上執行GET請求。因此,只需在您的重定向中提供303狀態代碼即可:

res.redirect(303, '/test')