(圖片來源)
我在表單的上傳檔案欄位選擇一個約 9MB 的 pdf 檔案
當我按下送出表單的時候出現下面的錯誤訊息:
看的出來第一行錯誤訊息是我上傳檔案的大小超過 php 設定的上傳最大限制,9735099(9.xxMB) 是我上傳的檔案, 而 8388608(8MB) 是 php 設定 post 上傳最大限制,奇怪的是,為什麼會出現 TokenMisMatchException in VerifyCsrfToken.php 錯誤? (TokenMisMatchException)
就我所知此錯誤是表單沒有加入 csrf token 才有的狀況,但是我明明就有加...
我在網路上找到了一篇文章,內容是說,當 post 的 size 超過 php 設定的最大值的時候,$_POST 和 $_FILES 全域變數會變空值,理所當然也不會有 CSRF token! (傳送門)
看完文章恍然大悟,但是總不能別人說什麼我們就相信什麼,老師常說:要保持懷疑的態度,那我們就來實驗一下是不是真的像他所說的一樣!
於是我進行了三種測試:
1. 夾帶檔案不超過 post size 最大值
2. 夾帶檔案超過 post size 最大值
3. 夾帶檔案超過 post size 最大值,但關閉 CSRF 檢查
首先我在接收表單資料的 Controller function 印出表單內容。
測試一、結果看起來相當正常
測試二、結果出現一樣的離奇錯誤
測試三、結果果真印出一個空陣列!連 CSRF token 都沒有!
經過這些實驗,我們要做的就是避免讓使用者產生這個頁面,這邊提供一個方法,在前端利用 javascript 做判斷,若使用者選擇的檔案超過 post 的最大值,就會跳出提醒視窗並且不會夾帶該檔案。
程式碼如下:
/** * 計算總共上傳大小是否超過5MB */ for( var i=1 ; i<=5 ; i++ ){ $("#uploader_"+i.toString()).on('change', function(){ var uploader_dom = document.getElementById("uploader_"+i.toString()); if( (uploader_dom.files[0].size/1024/1024)>5 ){ alert("{{trans('upload_lang.upload_file_exceeds_form_limit')}}"); uploader_dom.value = ""; } }); }
留言列表