2017-08-24 30 views
0

我有两个简单的HTML表单按钮,现在调用PHP函数发送电子邮件。除了一件事以外,一切正常。如果点击其中一个按钮发送报告,然后刷新页面,则该功能似乎再次被调用,并且电子邮件很好地再次出现,用户使用浏览器刷新按钮刷新页面。PHP按钮调用函数将导致函数重复刷新页面

如果页面刷新了,那么电子邮件会在点击最后一个按钮时再次熄灭。所以,如果我点击按钮1然后刷新页面,我会得到按钮1的两个报告。如果我点击按钮#1,然后点击按钮#2,只有第二个报告会出去。如果我点击按钮#2和#1,则只有报告#1会再次出现。

因此,无论点击多少个按钮,刷新页面将导致最后一次按钮点击(仅重复)。尝试取消设置请求参数(在下面的代码中)对由页面刷新引起的重复无效。

我不明白为什么(在页面刷新上)页面看到最后一次设置的按钮点击,以及为什么unset命令不起作用。

感谢您的任何帮助。

if(isset($_REQUEST['email_this_weeks_report'])) { 
    unset($_REQUEST['email_last_weeks_report']); 
    #send email now email code for this week 

}  
if(isset($_REQUEST['email_last_weeks_report'])) { 
    unset($_REQUEST['email_last_weeks_report']); 
    #send email now email code for last week 

} 

<form>   
    <input class="ui-button ui-widget ui-corner-all" type="submit" 
name="email_this_weeks_report" value="Email This Weeks Report Now" /> 
</form> 

<form>   
    <input class="ui-button ui-widget ui-corner-all" type="submit" 
name="email_last_weeks_report" value="Email Last Weeks Report Now" /> 
</form> 
+0

你在两个if条件中都设置了相同的东西 –

+0

_“我不明白为什么(在页面刷新时)页面看到最后一个按钮设置为”_“ - 因为浏览器确切同样的请求再次...这是什么刷新_means_。 _“以及为什么未设置的命令不起作用”_ - 因为开始时是无稽之谈。如果您发送表单的时间是_first_,那么它会执行同样的操作 - 所以如果_did_按照您的想法工作,它会从一开始就破坏您的功能。您正试图在_identical_两个请求之间_differentiate_ ...当然不能工作。 – CBroe

回答

2

单击按钮提交表单。

表格中的数据被捆绑并包含在请求中。

另外:您正在使用method=GET,默认值,但您没有提出“安全”请求。你是的东西,而不是得到信息。您应该使用POST请求。

当您单击刷新时,您告诉浏览器再次发出请求并显示新版本的页面。

由于请求中包含了“发送特定邮件”的查询字符串,因此它会再次发送该邮件。在$_REQUEST


取消设置值没有效果,因为当浏览器发出一个请求与它相同的数据:$_REQUEST刚刚被重新填满。


你应该使用the PRG pattern处理这个:

  1. 提交使用method=POST
  2. 有你的PHP脚本程序的形式在表单中的数据(即发送邮件)然后重定向到一个不同的PHP脚本
  3. 让新的PHP脚本显示结果(在这种情况下,没有结果,它的形式,你可以使用一个普通的HTML文件,没有PHP在我T)。
+0

有没有办法重定向到同一页面或停留在同一页面上?看起来很烦人,不得不建立一个登陆页面来解决这个问题并强制用户点击回来。将重定向添加回当前确实询问您是否要重新设置saly:\t \t header(“Location:export_current_week.php”,true,301); \t \t exit(); – Reno

+0

我最终喜欢这样做更好,只要去一个“成功通过电子邮件发送”的通知页面,并返回一个链接。记住并理解我很简单,而不会真的使事情过分复杂化。谢谢您的帮助! – Reno

1

变化

<form> 

<form method='POST'> 

一个简单的方法来防止多次提交是随机令牌的隐藏输入添加到窗体。

<input type='hidden' name='formtoken' value='<?= uniqueid() ?>'/> 

每次从服务器获取页面时,此隐藏变量的值都会改变。因此,在服务器端,您可以通过检查具有此唯一标识的表单是否之前已提交,以防止重新提交相同表单。

session_start(); 
$sessionToken = $_SESSION['formtoken']? : null; 
$currentToken = $_POST['formtoken']? : null; 

// If no session token yet: form has never been submitted 
if(!$sessionToken): 
    // save the current token in session so we'll recognize it next time 
    $_SESSION['formtoken'] = $currentToken; 
    /* ok to send the email */ 

// ElseIf current token was already used: Duplicate form submission 
elseif($sessionToken === $currentToken): 
    /* don't send the email!*/ 

// Else session token exists, but current token is new: User fetched a new form from server 
else: 
    // update the session token 
    $_SESSION['formtoken'] = $currentToken; 
    /* ok to send the email */ 

endif; 

当用户刷新时,浏览器会询问她是否要重新提交表单。如果她这样做,你会知道,因为当前令牌和会话令牌将是相同的。这取决于你决定如何处理它。

+0

这并不能解决问题。它只是鼓励浏览器在用户点击刷新时询问用户是否真的想刷新页面。 – Quentin

+0

@Quentin好点。我会添加一些或删除。 – BeetleJuice

+0

是的,这是我得到的行为。如果刷新页面,浏览器会询问您是要重新提交还是取消 – Reno

1

使用GET或POST表单刷新页面将重新提交数据(虽然它会首先在POST方案中询问您应该使用的方式)。

尝试重定向表格后,用户提交

if(isset(...)){ 
    // Do your logic 
    header('Location: https://you_site.com/your-form-page?thank-you'); 
    exit; 
} 

这必须别的是在页面上输出之前完成。

+0

它不是POST表单。 – Quentin

+0

其他答复中的人士表示,将表单转换为POST将解决问题。是指那个。 – spaceman

+2

答案应该回答这个问题,他们不应该回答其他答案。 – Quentin

相关问题