2017-08-24 68 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