【问题标题】:Why POST redirects to GET and PUT redirects to PUT?为什么 POST 重定向到 GET 而 PUT 重定向到 PUT?
【发布时间】:2016-01-17 19:37:45
【问题描述】:

我正在使用 express 4.13.3(最新)和以下代码:

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 相同)?

【问题讨论】:

    标签: node.js http express


    【解决方案1】:

    在深入了解细节之前,以下是解决问题的一种方法:

    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 请求重定向。

    【讨论】:

    • 但是为什么要快速重定向 PUT -> PUT 和 POST -> GET? POST/PUT 应该“平等地”重定向,对吗?似乎 express 自动将 303 用于 POST 和 302 用于 PUT?
    • @user606521 最新的 HTTP 1.1 规范明确允许 302 重定向将 POST 更改为 GET。 (请参阅我的回答中来自 RFC 的相关引用。)该规范不允许除特定的 POST-to-GET 更改之外的任何其他转换,因此 PUT 仍然是 PUT。这是出于历史原因;即,浏览器错误地实现了原始规范并且规范更改以允许此错误。
    • 在我看来,“默认情况下,Express 使用 HTTP 代码 302 进行重定向。根据 HTTP 规范,这可以防止 POST/PUT 请求被重定向为 POST/PUT 请求,并解释了你的在您的代码中观察到”是对规范和 OP 问题的误解。首先,302 不会阻止 POST/PUT 被重定向为 POST/PUT,它会阻止非 GET/HEAD 方法的自动重定向。 (有关其他信息,请参阅 aspillers 评论)。 (1/2)
    • 其次,OP 明确表示它看到这两种方法的不同行为,因为实现不遵守规范,并且这种情况以不统一的方式发生(尽管在眼镜)。要结束此评论,请注意 303 不仅允许而且建议它确实诱导使用 GET 方法(尽管如果在特定情况下存在正当理由,可以做其他事情)。 (2/2)
    【解决方案2】:

    首先,我们来了解一下res.redirect does

    res.redirect([status,] 路径)

    重定向到从指定路径派生的 URL,具有指定的 HTTP 状态代码状态。如果不指定状态,状态码默认为“302“找到”。

    如果我们查看HTTP 1.1 spec for a 302 response,我们会看到

    注意:由于历史原因,用户代理可能会更改请求 从 POST 到 GET 的方法用于后续请求。如果这 行为是不希望的,307(临时重定向)状态代码 可以改用。

    307 请求将在所有情况下保留 HTTP 动词,但这不是您想要的。您希望动词更改为 GET。在这种情况下,您需要303

    303 查看其他

    303 (See Other) 状态码表示服务器是 将用户代理重定向到不同的资源,如 Location 标头字段中的 URI,旨在提供 对原始请求的间接响应。用户代理可以执行 以该 URI 为目标的检索请求(GET 或 HEAD 请求,如果 使用 HTTP),它也可能被重定向,并呈现最终的 结果作为对原始请求的答复。

    303 响应将提示客户端(假设它理解 HTTP 1.1)对指定资源执行 GET 请求。因此,只需在重定向中提供 303 状态代码:

    res.redirect(303, '/test')
    

    【讨论】:

      【解决方案3】:

      put的方式是正确的,你是把请求重定向到另一个位置,但是http的方式是一样的。这就是它试图再次访问put 的原因。(您没有更改 http 方法。)

      为什么post 会重定向到get

      这里是answer

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 2017-07-02
        • 2016-09-15
        • 2014-06-04
        相关资源
        最近更新 更多