在一篇关于防止PHP表单重新提交的文章中,我读到了以下内容:
(不引用)这可能是接收表单数据的页面,例如名为"form.php":
<form action="submit.php">
<input type="text" name="user" required />
<input type="password" name="pass" required />
<input type="submit" value="Log in" />
</form>
因此,处理POST数据的页面将被称为"submit.php"。如果登录正常,下面的代码将运行:
header('Location: /login/form.php?success=true');
但是,用户不能直接导航到上面的URL吗?另外,GET变量的目的是什么?我能否在form。php中编写一个脚本来检查用户是否登录?
在submit.php中,我是否应该将登录的用户名保存为$_SESSION['username'],然后检查isset() At form.php?另外,由于带有"成功"的URL并不漂亮,再次重定向用户是否经济?我应该使用PHP header()还是Javascript window.location.href?如你所见,我有点困惑。
谢谢你的帮助。
但是,用户不能直接导航到上面的URL吗?
是的,他可以。但这不会导致任何不好的事情。
还有,GET变量的目的是什么?
有一些标志,表示表单已成功处理,您需要向用户表示祝贺。
我不能有一个脚本在form.php检查用户是否登录?
嗯,你可以按照你喜欢的方式保存你的代码。没有任何强要求
在submit.php中,我是否应该将登录的用户名保存为$_SESSION['username'],然后检查isset()是否在form.php中?
如果您需要在当前会话中持久化它-是的,这样做。
另外,由于URL中有"成功",它不是真的漂亮,它是经济的重定向用户一次?
重定向。重定向是很便宜的。
我应该使用PHP header()还是Javascript window.location.href?
你绝对应该在php中这样做,否则你会遇到你试图避免遵循prg方式的麻烦。
PRG或Post/Redirect/Get只是一种可以用来防止消息框的模式。具体如何使用取决于你的需要(这篇文章只是一个一般性的建议)。
如果你想在cookie或会话或get变量中标记成功的flash消息,这完全取决于你。第二个重定向没有帮助,顺便说一句,你会知道,如果你玩它。
唯一重要的部分是,在收到POST请求之后,执行重定向。然后,用户仍然可以在历史中来回移动,而不会被要求重新提交POST数据。
模式起作用了,这是一件好事。就在两天前,我又做了一次,一步一步的weppapp安装程序在浏览器界面上导航要好得多。
关于你的重定向这个代码是错误的:
header('Location:/login/form.php?success=true');
首先,你需要在冒号后面有一个空格:
header('Location: /login/form.php?success=true');
地址必须是一个绝对的URI,它必须包含完整的URL:
header('Location: http://example.com/login/form.php?success=true');
在header()
的旁边,你应该按照RFC提供一个消息体,许多所谓的"web开发人员"甚至不知道:
$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('<a href="%s">Moved</a>.', $url);
exit;
别忘了出口。当然,这是在重复工作,而不是安装PHP的http扩展,只做这一行:
http_redirect('/login/form.php?success=true');
你可以在这里找到这个漂亮的助手。
总结一下:重要的是你在发布后进行重定向。其他的事情,比如传递一个变量,完全取决于你想怎么做。
是的,您永远不应该依赖GET变量(甚至是隐藏的POST变量)来表示,"当然,让我进入,我是一个有效的用户!"
就我个人而言,我会从链接中剥离GET信息,并完全依赖会话变量。如果您正在使用PHP激活会话,请记住将'session_start();'作为第一行代码。
submit.php:
<?php
session_start();
if ($_POST['user'] && $_POST['pass']) { // Make sure both variable are set
if (your_method) {
// Code to check if the user and pass are valid however you plan
$_SESSION['user'] = $_POST['user'];
$_SESSION['loggedin'] = time();
}
}
header('Location: form.php'); // Either way, pass or fail, return to form.php
exit();
?>
Then in form.php:
<?php
session_start();
$activeuser = false;
if ($_SESSION['user'] && $_SESSION['loggedin'] < (time()+600)) {
// Check if the user exists and the last access was with in 10 minutes.
$_SESSION['loggedin'] = time(); // If so, keep them up to date!
$activeuser = true;
}
if ($activeuser) {
// whatever should show to someone logged in
} else {
// Show log in form
}
?>
另外,您可能已经知道这一点,但是默认的传输方法是GET,所以一定要在表单标签中指定method="post"。
如果需要,通常最好使用header()来重定向,因为Javascript是客户端,可以避免这会破坏您的网站功能的意图。
POST/REDIRECT/GET背后的主要思想,正如您链接到的文章所指出的那样,是为了避免用户(大多数时候)重新提交数据。一般来说,您不希望相同的POST(使用完全相同的数据)发生两次——实际上,在某些情况下,它最终可能会执行某些操作(例如从信用卡中扣款)第二次,这将是糟糕的。
你在问题中问的大部分都是实现细节(比如在重定向中发送?success请求参数)。
在实践中,通常发生的情况是您的重定向成功。例如,如果用户的输入验证失败,则不重定向,而是重新显示表单和相关的错误消息。这是一个基本的例子,都在一个脚本中。我尽量只包含重要的内容,尽可能少地包含无关的内容。
login。
<?php
/**
* ensure user supplied both username & password
* @return mixed true or an array of error messages
*/
function validate_login_values($vars){
$errors = array();
if (empty($vars['username'])) $errors[] = 'You must supply a username, genius.';
if (empty($vars['password'])) $errors[] = 'You must supply a password, dummy.';
if (empty($errors)) return true;
return $errors; // $errors must be an array.
}
if (! empty($_POST)){
$validationResults = validate_login_values($_POST);
if ($validationResults === true){
// assume here that authenticate properly escapes it's arguments before sending them
// to the database.
if (authenticate($_POST['username'],$_POST['password'])){
//GREAT SUCCESS! The user is now logged in. Redirect to home page
header("Location: /");
die();
}
$errors[] = 'Invalid username/password. Try again, slim";
}else{
$errors = $validationResults; // validate_login_values created errors.
}
}
?>
<h1>Log In, Friend!</h1>]
<?php
//display errors, if there were any
if (! empty($errors)): ?>
<div class="errors">Something went horribly wrong:
<ul><?php foreach($errors as $e) echo "<li>$e</li>"; ?></ul>
<div>
<?php endif; ?>
<form method="POST">
<!-- //username, password, and submit -->
</form>