PHP提交表单时如何防止多次插入?
有时,用户可能会按两次 Enter
,帖子就会插入两次。
除了检查是否已经存在具有相同 title
和 content
的帖子之外,是否有解决方案可以防止这种情况发生?
Sometimes the user may press Enter
twice, and the post is inserted twice.
Is there a solution to prevent this other than check if there is already a post with the same title
and content
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
此问题有多种解决方案:
在发布表单时使用 Javascript 禁用表单的提交按钮。这样做的缺点是,这绝对不是万无一失的方法。无需实际单击按钮即可提交表单非常容易,这对于禁用 JavaScript 的用户也不起作用。 我绝对不会推荐这种方法。
示例:
使用PHP 会话 将会话变量(例如 $_SESSION['posttimer'])设置为发布的当前时间戳。在 PHP 中实际处理表单之前,请检查 $_SESSION['posttimer'] 变量是否存在,并检查是否存在一定的时间戳差异(即:2 秒)。这样,您就可以轻松过滤掉重复提交。
示例:
在每个 POST 上包含唯一的令牌。在这种情况下,您还可以将会话变量设置为要包含的令牌,然后呈现该令牌在形式中。提交表单后,您将重新生成令牌。当提交的令牌与您会话中的令牌不匹配时,表单已重新提交,并且应被声明为无效。
示例:
There are several solutions to this problem:
Use Javascript to disable the form's submit button when it is posted. Downside to this is that this is ABSOLUTELY not a foolproof way. It's very easy to submit forms without actually clicking the button, and this would also not work for users with JavaScript disabled. I would definitely not recommend this method.
Example:
Use PHP sessions to set a session variable (for example $_SESSION['posttimer']) to the current timestamp on post. Before actually processing the form in PHP, check if the $_SESSION['posttimer'] variable exists and check for a certain timestamp difference (IE: 2 seconds). This way, you can easily filter out double submits.
Example:
Include a unique token on each POST. In this case, you would also set a session variable to the token you want to include and then render the token in the form. Once the form is submitted, you re-generate the token. When the submitted token does not match the token in your session, the form has been re-submitted and should be declared invalid.
Example:
在帖子中使用唯一的令牌,以便每个帖子/回发仅处理一次。
禁用提交按钮并不是一个很好的解决方案,因为人们可能会关闭 JavaScript,或者做其他奇怪的事情。客户端验证是一个好的开始,但也应该始终与服务器端处理一起支持。
Use a unique token with the post, so that each post/postback is only handled once.
Disabling the submit button is not a very good solution since people could have javascript turned off, or doing other weird things. Client side validation is a good start, but should always be backed up with server side handling as well.
生成一个唯一的一次性使用密钥以与表单一起提交。
依赖 Javascript 是一个坏主意,因为它可能已被用户在客户端中禁用。使用密钥方案,当服务器接收到提交时,可以锁定该密钥的提交。您可以根据自己的喜好回复重复提交的内容。
为了使这种方法发挥作用,密钥必须是唯一的并且很难预测。否则,某些表单可能会因按键冲突而被锁定。因此,您不必跟踪每个表单提交的密钥并避免冲突,密钥应该随着该用户的会话而过期。另一件需要注意的事情是,如果恶意用户能够预测密钥,您的代码可能容易受到某种劫持或 DOS 攻击。
Generate a unique, one-time use key to submit with the form.
Relying on Javascript is a bad idea because it may have been disabled in the client by the user. With the key scheme, when the submit is received by the server, submission for that key can be locked. You can respond to duplicate submits however you like.
For this approach to work, keys must be unique and very difficult to predict. Otherwise some forms could be locked due to key collisions. So you don't have to track keys for every form submission and avoid collisions, keys should expire with that user's session. The other thing to watch out for is if malicious users are able to predict the key, your code may be vulnerable to some kind of hijacking or DOS exploit.
提交表单后,使用 Javascript 禁用提交按钮 (
onsubmit
)。请注意,如果用户禁用了 Javascript,他们仍然可以提交两次。这种情况是否经常发生足以证明检查代码是合理的(正如您在问题中所建议的那样)取决于您。
Disable the submit button using Javascript once the form gets submitted (
onsubmit
).Note that if the user has disabled Javascript, they can still submit twice. Whether or not this happens often enough to justify also checking in your code (as you suggested in your question) is up to you.
或者,使用一次性表单键。
Alternatively, use one-time form keys.
我使用这个:
将 $form_token 与表单一起发送,然后...
我检查 form_token:
I use this:
send $form_token with the form, then...
I check the form_token:
用户使用 JavaScript 提交表单后禁用提交按钮。例如,这就是 StackOverflow 在您回答问题时使用的内容。
例如
disable the submit button once the user has submitted the form, using JavaScript. That is what, for example, StackOverflow uses when you answer a question.
For example
按提交两次很少会导致多次插入,但如果您想要一个非常简单的解决方案,请
在表单标记中使用,前提是您提供提交按钮
id="submit"
Pressing submit twice quite rarely results in multiple inserts, but if you want a dead-simple sollution, use
in the form tag, provided you give your submit button
id="submit"
单击按钮后立即使用 JavaScript 禁用该按钮。
Use a JavaScript to disable the button as soon as it is clicked.
创建确认页面的另一种方法,用户最终可以在其中按下提交按钮。它可能会减少这种可能性。
Another way to create a confirmation page where user can finally press the submit button. It might reduce the possibilities of this kind.
我正在对 action.php 执行以下操作
注意:始终使用 session_start() 在标头中启动会话;
I'm doing the following on the action.php
Note: Always initiate your sessions in the header using session_start();
Aron Rotteveel 的在每个帖子上包含一个唯一的令牌对我有用。但是,当用户刷新页面(F5)时,我的表单仍然会提交。我设法通过添加重置来解决这个问题:
我的最终脚本如下:
哦!不要忘记在
之前添加
session_start();
我是 PHP 新手,如果您发现违规行为,请纠正我。
Aron Rotteveel's Include a unique token on each POST worked for me. However, my form still submits when a user refreshes the page (F5). I managed to solve this by adding a reset:
my final scripts goes like:
oh! don't forget to add
session_start();
before<!DOCTYPE>
I am a PHP newbie so please correct me if you find irregularities.
使用 JavaScript 阻止其发送
Use JavaScript to stop it from sending