2015-10-19 118 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') 
相关问题