使用 PRG 模式在最后一页显示表单数据的好方法是什么
what is a good way to display form data on last page using PRG pattern
我想使用 PRG 模式来防止表单重新提交,因为提交涉及发送邮件。但是,这种方法的问题是,我似乎没有找到 "right" 向用户显示重定向后发送了哪些数据的方法。目前我正在做类似的事情:
某些页面的形式为 (index.html
)
<form action="handleform.php" method="post">
<input type="text" name="name" placeholder="Name" required />
<input type="text" name="tel" placeholder="Telephone" />
<input type="email" name="mail" placeholder="E‑Mail" required />
<!-- and more input fields -->
</form>
一些处理表单数据的脚本handleform.php
<?php
$data[0] = filter_var(INPUT_POST, "name", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data[1] = filter_var(INPUT_POST, "tel", FILTER_SANITIZE_NUMBER_INT);
$data[2] = filter_var(INPUT_POST, "mail", FILTER_VALIDATE_EMAIL);
// process rest of data and create mail
$mail->Body = getNiceHTML($data);
$mail->send();
header("Location: formhandled.php?id=" . urlencode($mail->Body));
exit();
?>
以及成功后显示的脚本页面formhandled.php
<!-- header and menu html -->
<?php
echo $_GET["id"];
?>
<!-- footer html -->
这种方法的问题是我认为这会暴露 URL 中所有输入的数据,因此可能太容易受到攻击。最重要的是,HTML 字符串使 URL 相当冗长。我可以想到其他两种方法来解决我的问题
- 将字符串存储在一个(临时)文件中并传递文件名,但是在我离开
formhandled.php
之后我需要找到一些方法来删除这些文件以防止此信息保留服务器比必要的时间更长。
- 开始会话。这种方法的主要问题是,如果用户没有禁用 cookie(如果我理解正确的话),我只能显示数据。
但我不明白为什么这些会是 better/worse。我也无法想象没有人做过这样的事情,但我找不到任何关于如何解决这个问题的信息。
所以我的问题是:如何在重定向后显示输入的表单数据?
有两种传输数据的方法:
- 在客户端传输它,在重定向的情况下意味着通过 URL 或可能的 cookie。
- 在服务器端传输它,这意味着服务器存储数据并在下一页再次检索它。
你已经差不多明白了。在客户端传输它确实有点令人讨厌;你真的不想把所有这些信息都放到 URL 中(不是因为 "vulnerabilities",只是将数据从 URL 打印到屏幕上没有太多问题),并且您希望避免为此设置 cookie。
最好的解决办法差不多:
- 服务器将数据存储在具有唯一 ID 的短期自动清除位置
- 您通过 URL 作为查询参数发送唯一 ID
- 你从带有id的短期位置检索数据,显示它,然后丢弃它
现在,什么才算是好的短期存储?会话会很好,您可以通过 URL 而不是 cookie 来传输会话 ID。这可能是使用内置 PHP 工具的最简单的解决方案。或者,像 Redis 存储或类似的内存存储之类的东西对于这种情况非常有用;但是仅仅为了这个目的而设置可能有点矫枉过正。如果您已经 运行 建立了数据库,则可以将数据存储在那里。
无论选择哪种方案,都必须保证数据迟早会被自动丢弃。如果出于某种原因用户没有访问重定向页面,临时存储的数据将堆积在您的服务器上,这是您要避免的。会话自动垃圾收集,Redis 数据可以自动清除,并且您可以使用数据库 运行 通过各种机制进行偶尔的清理查询。
我想使用 PRG 模式来防止表单重新提交,因为提交涉及发送邮件。但是,这种方法的问题是,我似乎没有找到 "right" 向用户显示重定向后发送了哪些数据的方法。目前我正在做类似的事情:
某些页面的形式为 (index.html
)
<form action="handleform.php" method="post">
<input type="text" name="name" placeholder="Name" required />
<input type="text" name="tel" placeholder="Telephone" />
<input type="email" name="mail" placeholder="E‑Mail" required />
<!-- and more input fields -->
</form>
一些处理表单数据的脚本handleform.php
<?php
$data[0] = filter_var(INPUT_POST, "name", FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$data[1] = filter_var(INPUT_POST, "tel", FILTER_SANITIZE_NUMBER_INT);
$data[2] = filter_var(INPUT_POST, "mail", FILTER_VALIDATE_EMAIL);
// process rest of data and create mail
$mail->Body = getNiceHTML($data);
$mail->send();
header("Location: formhandled.php?id=" . urlencode($mail->Body));
exit();
?>
以及成功后显示的脚本页面formhandled.php
<!-- header and menu html -->
<?php
echo $_GET["id"];
?>
<!-- footer html -->
这种方法的问题是我认为这会暴露 URL 中所有输入的数据,因此可能太容易受到攻击。最重要的是,HTML 字符串使 URL 相当冗长。我可以想到其他两种方法来解决我的问题
- 将字符串存储在一个(临时)文件中并传递文件名,但是在我离开
formhandled.php
之后我需要找到一些方法来删除这些文件以防止此信息保留服务器比必要的时间更长。 - 开始会话。这种方法的主要问题是,如果用户没有禁用 cookie(如果我理解正确的话),我只能显示数据。
但我不明白为什么这些会是 better/worse。我也无法想象没有人做过这样的事情,但我找不到任何关于如何解决这个问题的信息。
所以我的问题是:如何在重定向后显示输入的表单数据?
有两种传输数据的方法:
- 在客户端传输它,在重定向的情况下意味着通过 URL 或可能的 cookie。
- 在服务器端传输它,这意味着服务器存储数据并在下一页再次检索它。
你已经差不多明白了。在客户端传输它确实有点令人讨厌;你真的不想把所有这些信息都放到 URL 中(不是因为 "vulnerabilities",只是将数据从 URL 打印到屏幕上没有太多问题),并且您希望避免为此设置 cookie。
最好的解决办法差不多:
- 服务器将数据存储在具有唯一 ID 的短期自动清除位置
- 您通过 URL 作为查询参数发送唯一 ID
- 你从带有id的短期位置检索数据,显示它,然后丢弃它
现在,什么才算是好的短期存储?会话会很好,您可以通过 URL 而不是 cookie 来传输会话 ID。这可能是使用内置 PHP 工具的最简单的解决方案。或者,像 Redis 存储或类似的内存存储之类的东西对于这种情况非常有用;但是仅仅为了这个目的而设置可能有点矫枉过正。如果您已经 运行 建立了数据库,则可以将数据存储在那里。
无论选择哪种方案,都必须保证数据迟早会被自动丢弃。如果出于某种原因用户没有访问重定向页面,临时存储的数据将堆积在您的服务器上,这是您要避免的。会话自动垃圾收集,Redis 数据可以自动清除,并且您可以使用数据库 运行 通过各种机制进行偶尔的清理查询。