一陣子沒有開 Google Analytics 看資料分析了,無意間發現瀏覽器市場有急大的改變:Google 瀏覽器變成主流。
敝站流量不多,但是跟十年前來比較,瀏覽器的市場的確有很大的改變。
ps. 以後可以不用考慮 IE 系列瀏覽器了 (逃)
Post/Redirect/Get (PRG) pattern 是一種處理表單資料的流程,可以防止使用者回上一頁、或是使用重新整理的方式重複送出表單資料。
再拿留言板舉例 (萬年題材 XD),假設在 form.html 填寫完表單,送出到資料到 post.php,而 post.php 處理資料後直接將結果顯示出來 (傳回 HTML),這個時候再瀏覽器按下「重新整理」按鈕,變會看到提示訊息,詢問是否要重送表單內容。
此時若重送表單資料,則會重新送出一模一樣的內容,若 post.php 沒有特別檢查,就會重複處理。很久以前開心農場就是用這種方法洗禮物的。
為了避免瀏覽器可以重新整理頁面,將資料處理的流程稍微做個調整:
post.php 寫法大致如下:
if(saveData($_POST)){
$status = 'ok';
}else{
$status = 'error';
}
header('Location: done.php?status=' . $status);
由於使用 HTTP 3xx 重新導向,瀏覽器不會將 post.php 紀錄到瀏覽紀錄中,按下「上一頁」按鈕也是回到 form.html 而非 post.php,且 done.php 使用 HTTP GET 方式取得內容,所以重新整理頁面也不會重新送出表單內容。此流程按照三個步驟的 HTTP request 方式稱為 Post/Redirect/Get pattern。
PRG pattern 寫起來至少會有三個頁面要實作,也是挺麻煩的。若還要簡單一點的方式,那大概就是改用 AJAX 處理表單了吧。
Reference:
Post/Redirect/Get – Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Post/Redirect/Get
在無限期鬼打牆以後,才發現 HTTP Referer 不一定真的代表參考位址。
假設有三個頁面:
一般情況下 process.php 的 referer 會是 form.html、showError.php 的 referer 會是 process.php,但若 proccess.php 跳轉頁面是這樣寫:
if( ERROR ){
header('Location: showError.php');
}
執行後 HTTP server 的回應會是 HTTP 302 而非 HTTP 200,瀏覽器不會將 302 視為正常的瀏覽行為,所以 proccess.php 不會被列入正式瀏覽記錄,當重新導向到 showError.php 時,Refer 仍然會是最後一個正式的瀏覽記錄,也就是 form.html。
若希望讓 showError.php 可以正確知道是哪一頁連過來的,就得靠其他方法了。
在這裡建議不要使用 HTTP Referer 來做判斷的依據。現有瀏覽器開發工具、外掛都可以讓人任意修改 Referer,也聽說有些防毒軟體會固定將 Referer 從 HTTP request 中刪除,再者,各家瀏覽器送 Referer 的情況也不同 (IE MUST DIE),用 Referer 判斷流程等方法會遇到不少例外情況要處理,別讓自己那麼累。
Reference:
php – HTTP_REFERRER and Location redirect – Stack Overflow