理解"post/redirect/get"

wha*_*rak 26 html php forms session post-redirect-get

我很难理解"post/redirect/get"的确切过程.我已经梳理了这个网站和网络几个小时,除了"这里的概念"之外什么都找不到.它是如此简单,它不需要一步一步的教程?有谁知道我可以用来查找示例或教程的好网站或书籍?

Mas*_*tic 52

维基百科很好地解释了这一点!

问题

问题

解决方案

解决方案

  • 嗯,这个图形比读取大量文本更清晰. (14认同)
  • @Vaibhav 是的,这是 PRG 模式无法解决的问题,你真的会得到重复的帖子。如果您遇到此问题,请参阅[此](http://stackoverflow.com/q/16814157)以获取更多信息。我会使用 rogueleaderr 的[这个答案](http://stackoverflow.com/a/21845938/825637)中的选项。 (2认同)

ick*_*fay 22

您可能从研究POST了解到,-redirect- GET看起来像这样:

  • 客户端获取带有表单的页面.
  • 表单POST到服务器.
  • 服务器执行操作,然后重定向到另一个页面.
  • 客户端遵循重定向.

例如,假设我们有这个网站的结构:

  • /posts (显示帖子列表和"添加帖子"的链接)
    • /<id> (查看特定帖子)
    • /create(如果使用该GET方法请求,则将表单发布返回给自己;如果是POST请求,则创建帖子并重定向到/<id>端点)

/posts 本身与这种特殊模式并不真正相关,所以我会把它留下来.

/posts/<id> 可能会像这样实现:

  • 在数据库中查找具有该ID的帖子.
  • 使用该帖子的内容呈现模板.

/posts/create 可能会像这样实现:

  • 如果请求是GET请求:
    • 显示一个空表单,目标设置为自身,方法设置为POST.
  • 如果请求是POST请求:
    • 验证字段.
    • 如果存在无效字段,请再次显示表单并指出错误.
    • 否则,如果所有字段都有效:
      • 将帖子添加到数据库.
      • 重定向到/posts/<id>(<id>从调用数据库返回的位置)

  • @whatdafrak:并非总是如此。POST用于修改事物的动作。GET用于仅显示事物但不修改任何信息的页面。 (2认同)

Sar*_*tha 7

我会试着解释一下.也许不同的视角可以帮到你.

使用PRG,浏览器最终会发出两个请求.第一个请求是POST请求,通常用于修改数据.服务器响应响应中的Location标头,并且正文中没有HTML.这会导致浏览器重定向到新的URL.然后,浏览器向新URL发出GET请求,该URL响应浏览器呈现的HTML内容.

我将尝试解释为什么应该使用PRG.GET方法永远不应该修改数据.当用户单击链接时,浏览器或代理服务器可能会返回缓存的响应,而不会将请求发送到服务器; 这意味着当您想要修改数据时,不会修改数据.此外,POST请求不应该用于返回数据,因为如果用户想要获取数据的新副本,则他们被迫重新执行请求,这将使服务器再次修改数据.这就是为什么浏览器会给你一个模糊的对话框,询问你是否确定要重新发送请求,并可能再次修改数据或第二次发送电子邮件.

PRG是POST和GET的组合,它们使用每个用于它们的用途.


ima*_*ork 5

只是为了让人们可以看到一个代码示例(这是使用express):

app.post('/data', function(req, res) {
  data = req.body;  //do stuff with data
  res.redirect('public/db.html');
});
Run Code Online (Sandbox Code Playgroud)

因此,澄清一下,它会立即刷新网页,因此刷新该网页(例如,如果您更新了其中的元素),它不会重新发布表单数据。

我的代码曾经是这样的:

app.post('/data', function(req, res) {
   data = req.body;
   res.sendFile('public/db.html');
});
Run Code Online (Sandbox Code Playgroud)

所以这里的响应是在 /data 地址发送 html 文件。因此,在地址栏中,按下提交按钮后,它会为我显示:localhost:8080/data。但这意味着在刷新该页面时,如果您刚刚提交了表单,它将再次提交。并且您不希望同一个表单在数据库中提交两次。因此,将其重定向到网页(res.redirect)而不是发送文件(res.sendFile),会停止该表单的重新提交。