在使用flash上傳檔案時,當檔案超過一定大小,會遇到錯誤:
如何遇到這個問題的:
去年曾經使用Extjs開發一個遊戲運維內建系統,其中有一個功能是使用flash上傳檔案,例如excel、sql等,背景程式來處理上傳的檔案。而這個flash上傳工具是我之前寫的,可是同僚現在在系統中上傳一個2M多的檔案時,傳到40%左右就提示出現io錯誤,讓人查一下是否是flash有逾時的情況。
看到這個問題我也覺得很奇怪,因為flash在選擇檔案的後就判定它的大小了,是以flash不存在檔案過大或過小的情況。而flash向背景送出參數是否存在逾時,我第一反應是不存在(除非http協定或是web伺服器上面有逾時限制);flash做的隻是監聽和回調
那問題出在哪裡,最初我認識是背景伺服器的問題,比如上傳大小的設定限制等。因為背景使用java寫的,本機不太好模拟環境,隻能自己用php模拟背景來找到這個問題
為了保險起見,我用了兩種方案:
1、普通的form送出
2、flash的post送出
最初試的時候,用fiddler抓到的是請求php得到http的504錯誤(GameWay timeout,奇怪了…)
然後去驗證自己的想法,是否php裡有設定檔案大小的參數,找到php.ini,修改如下參數:
upload_max_filesize = 200M
post_max_size = 200M
(如果以上兩項設定的值小于post送出檔案大小,将得不到檔案的相關資訊,如temp_name、size等,但不會出現flash io error 2038,反複測試得到的結果)
當然還有其它參數需要修改,如:max_execution_time、max_input_time等.
詳情請參考:php.ini修改php上傳檔案大小限制
即使是我修改memory_limit=-1,修改所有php參數依舊出現錯誤,然後繼續搜尋
在swfupload的官網論壇裡找到這麼一篇關于IO Error #2038
仔細閱讀了下面的回複,看到有一條比較吸引人:
“Hello. I use nginx proxy and i see same error. I fixed in my site and now working fine.”
為何如此吸引我,因為我本機的web伺服器也使用的也是nginx
讀完以後,就先試試了,調參數,它上面的三個參數我都改了:
#keepalive_timeout 60;
#send_timeout 3m;
client_max_body_size 500m;
注釋前面兩個,修改最後一項為500m,預設大小好像是1m
它給出的示例配置如下:
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
sendfile on;
client_max_body_size 500m;
tcp_nodelay on;
gzip on;
server {
listen 80;
server_name domain.hu www.domain.hu;
access_log off;
location / {
proxy_pass http://xxxxxxxxxx:80/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/nginx-default;
}
}
}
關閉nginx應用程式,再重新開機它,重新整理、測試,居然好了…
好了以後,再反向推導産生問題的原因,先還原所有參數,再一個一個試,最終找到關鍵點:client_max_body_size這個參數
如果設定的大小過小,則會出現413 Request Entity Too Large錯誤(之前是504,這也讓我很奇怪,前面沒截到圖---遺憾)
确定是nginx的問題,然後回頭又折騰php的幾個參數,發現:如果upload_max_filesize或post_max_size的值比上傳的檔案要小,則将擷取不到檔案的相關資訊,但不報錯。
$_FILES["Filedata"]["error"] == 0;
print_r($_FILES);
至于換成Apache是否會遇到這個問題,我就不清楚了,沒測試過~