突破48MB限制:JS、php和apache視頻切片上傳解決方案
在小型項(xiàng)目開發(fā)中,處理大文件上傳常常會(huì)遇到挑戰(zhàn)。本文將分享一個(gè)實(shí)際案例:使用JavaScript、PHP和Apache進(jìn)行視頻切片上傳時(shí),如何克服48MB文件大小限制的問(wèn)題。
問(wèn)題:48MB上傳瓶頸
項(xiàng)目中采用切片上傳方案,理論上支持2GB文件,每片1MB,最多2000片。然而,實(shí)際測(cè)試中,上傳超過(guò)48MB(約48片)后,后續(xù)請(qǐng)求返回500錯(cuò)誤。即使調(diào)整切片大小為10MB,問(wèn)題依然存在。
代碼分析與改進(jìn)
JavaScript代碼:
原代碼中,F(xiàn)ormData對(duì)象僅初始化一次,導(dǎo)致每次請(qǐng)求都攜帶所有已上傳切片數(shù)據(jù),最終超過(guò)Apache的fcgidmaxrequestlen限制。
立即學(xué)習(xí)“PHP免費(fèi)學(xué)習(xí)筆記(深入)”;
改進(jìn)后的JavaScript代碼如下,關(guān)鍵在于每次發(fā)送請(qǐng)求前重新實(shí)例化FormData對(duì)象:
function videoFileUpload() { const LENGTH = 1024 * 1024; // 1MB let start = 0; let end = start + LENGTH; let blob_num = 1; let is_stop = 0; this.start = function () { const file = files.files[0]; const blob = cutFile(file); sendFile(blob, file); blob_num++; } // ... (其余代碼保持不變) ... function sendFile(blob, file) { if (is_stop === 0) { const xhr = new XMLHttpRequest(); const form_data = new FormData(); // 關(guān)鍵:每次重新實(shí)例化FormData const total_blob_num = Math.ceil(file.size / LENGTH); form_data.append('file', blob); form_data.append('blob_num', blob_num); form_data.append('total_blob_num', total_blob_num); form_data.append('file_name', file.name); xhr.open('POST', '/upload.php', false); // ... (其余代碼保持不變) ... } } // ... (其余代碼保持不變) ... }
PHP代碼:
PHP代碼中的文件合并邏輯也可能存在內(nèi)存效率問(wèn)題。對(duì)于超大文件,建議采用流式處理,避免一次性將所有切片讀入內(nèi)存。 (此處省略PHP代碼,因?yàn)樵a未提供明顯的內(nèi)存泄露或效率問(wèn)題,改進(jìn)重點(diǎn)在JS端)
解決方案總結(jié)
問(wèn)題的核心在于JavaScript代碼中FormData對(duì)象的重復(fù)使用。通過(guò)每次請(qǐng)求前重新實(shí)例化FormData對(duì)象,避免了數(shù)據(jù)累積,從而解決了48MB上傳限制。 對(duì)于PHP端,如果處理大文件時(shí)出現(xiàn)內(nèi)存問(wèn)題,則需要進(jìn)一步優(yōu)化文件合并邏輯,采用流式處理方式。 此改進(jìn)方案有效解決了大文件上傳問(wèn)題,確保了視頻切片上傳的穩(wěn)定性和可靠性。