JS、php和apache環境下大文件視頻切片上傳失敗的解決方法
使用JavaScript、PHP和Apache進行視頻切片上傳時,遇到48MB以上文件上傳失敗,并返回500錯誤碼的問題,通常是由于服務器配置或前端代碼邏輯錯誤導致的。本文分析問題根源并提供解決方案。
問題描述
在小型項目中,基于JavaScript、PHP和Apache的視頻切片上傳功能在處理超過48MB的文件時,服務器返回500錯誤,導致上傳失敗。調整切片大小和服務器配置后問題依然存在。
問題原因分析
經排查,問題主要源于前端JavaScript代碼處理FormData對象的方式存在缺陷。代碼中FormData對象僅初始化一次,后續每次切片上傳都在同一個FormData對象上追加數據。這導致每次請求都包含所有切片數據,請求體大小迅速膨脹,超過Apache的fcgidmaxrequestlen限制,最終觸發500錯誤。
解決方案
前端JavaScript代碼優化
關鍵在于每次發送請求前都創建一個新的FormData對象和XMLHttpRequest對象。修改后的代碼示例如下:
立即學習“PHP免費學習筆記(深入)”;
function videoFileUpload() { const CHUNK_SIZE = 1024 * 1024; // 1MB let start = 0; let end = start + CHUNK_SIZE; let blob; let blobNum = 1; let isStop = false; this.start = function() { const file = files.files[0]; blob = cutFile(file); sendFile(blob, file); blobNum++; }; this.stop = function() { isStop = true; }; function cutFile(file) { const fileBlob = file.slice(start, end); start = end; end = start + CHUNK_SIZE; return fileBlob; }; function sendFile(blob, file) { if (isStop) return; const xhr = new XMLHttpRequest(); const formData = new FormData(); // 新建FormData對象 const totalBlobNum = Math.ceil(file.size / CHUNK_SIZE); formData.append('file', blob); formData.append('blobNum', blobNum); formData.append('totalBlobNum', totalBlobNum); formData.append('fileName', file.name); xhr.open('POST', '/upload.php', true); // 使用異步請求 xhr.upload.onprogress = function(e) { // 上傳進度處理 }; xhr.onload = function() { if (xhr.status === 200) { // 上傳成功,繼續上傳下一片 if (blobNum <= totalBlobNum && !isStop) { blob = cutFile(file); sendFile(blob, file); blobNum++; } } else { // 上傳失敗處理 } }; xhr.onerror = function() { // 上傳錯誤處理 }; xhr.send(formData); } }
PHP后端代碼優化
PHP代碼中,如果文件合并操作直接讀取整個文件,可能會導致內存溢出。建議分批讀取文件內容進行合并,避免一次性加載所有切片數據到內存。
其他建議
- 檢查Apache的php_value upload_max_filesize和post_max_size設置,確保其值大于48MB。
- 檢查Apache的fcgidmaxrequestlen設置,將其值設置為一個足夠大的數值。
- 考慮使用更健壯的上傳庫,例如Flysystem。
通過以上調整,前端代碼能夠正確處理FormData對象,避免請求體過大,后端代碼優化則能防止內存溢出。 確保Apache配置允許上傳大文件,即可解決48MB以上文件上傳失敗的問題。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END
喜歡就支持一下吧
相關推薦