詳解利用plupload突破HTTP上傳限制

plupload 是一款國外的上傳開源組件,官方使用PHP做爲服務器語言。這篇文章主要介紹plupload的在上傳大文件方面的應用。javascript

plupload支持技術:php

1:Flash
2:Gears
3:HTML 5
4:Silverlight
5:BrowserPlus
6:HTML 4html

plupload主要功能:html5

1:突破HTTP上傳限制,可上傳大文件,官方論壇中有討論上傳2G文件的應用。
2:多文件隊列上傳
3:圖片自動生成縮略圖
4:上傳後自動生成惟一文件名
5:自定製UIjava

因爲plupload 確實是一個功能比較強大的組件因此沒法一一介紹全部功能特點,這裏主要就網站開發中plupload上傳大文件的問題進行思路與代碼的解析 。json

大文件上傳思路:plupload的上傳思路是將一個較大的文件分紅多個小塊進行上傳從而達到突破服務器上傳限制的目的。這估計也是惟一的方法了,但本人測試過程當中根據虛擬主機差別分塊上傳時對於可能會出現塊數太多中斷的緣由,但這確定是服務器的配置問題,更換服務器後該問題解決,也就是說大部分服務器均沒有問題的。數組


下載最新版本後按照官方DEMO進行安裝。瀏覽器

JS參數配置說明:緩存

<script type="text/javascript"> 

 $(function() {  
     $("#uploader").pluploadQueue({ 

         runtimes : 'gears,flash,silverlight,browserplus,html5',   // 這裏是說用什麼技術引擎,因爲國內瀏覽器問題這裏通常使用flash便可。其餘的刪除掉。          url : 'upload.php',  // 服務端上傳路徑          max_file_size : '10mb',  // 文件上傳最大限制。          chunk_size : '1mb',  // 上傳分塊每塊的大小,這個值小於服務器最大上傳限制的值便可。(文件總大小/chunk_size = 分塊數)。          unique_names : true,  // 上傳的文件名是否惟一          resize : {width : 320, height : 240, quality : 90},  // 是否生成縮略圖(僅對圖片文件有效)。           filters : [  
             {title : "Image files", extensions : "jpg,gif,png"},  
             {title : "Zip files", extensions : "zip"}  
         ],  // 這個數組是選擇器,就是上傳文件時限制的上傳文件類型           flash_swf_url : '/plupload/js/plupload.flash.swf',  // plupload.flash.swf 的所在路徑          silverlight_xap_url : '/plupload/js/plupload.silverlight.xap'  // silverlight所在路徑       });  
     
     // 這一塊主要是防止在上傳未結束前錶帶提交,具體你們可酌情修改編寫       $('form').submit(function(e) {  
         var uploader = $('#uploader').pluploadQueue();  // 取得上傳隊列          if (uploader.files.length > 0) {  // 就是說若是上傳隊列中還有文件              uploader.bind('StateChanged', function() {  
                 if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {  
                     $('form')[0].submit();  
                 }  
             });  
             uploader.start();  
         } else {  
             alert('You must queue at least one file.');  
         }  
         return false;  
     }); 

 });  
 </script>

 

因爲參數過多你們能夠到官方網站查看API參數說明。服務器

服務端代碼說明:
官方自帶了PHP版本的DEMO文件。你們必定要參考這個DEMO進行編寫或者直接使用。在此我簡單的作一下官方upload.php的註釋說明。

<?php// HTTP headers for no cache etc 頭部沒有緩存 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");header("Cache-Control: no-store, no-cache, must-revalidate");header("Cache-Control: post-check=0, pre-check=0", false);header("Pragma: no-cache");//上傳路徑  $targetDir = 'uploads/';// 腳本執行時間 @set_time_limit(5 * 60);// 延遲 // usleep(5000); // 接收 pluploa的參數 $chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';// 文件名整理 $fileName = preg_replace('/[^\w\._]+/', '', $fileName);// 這裏主要是若是JS參數設置了惟一文件名,則進行惟一文件名的處理,chunks<2 的意思是隻有在不分塊上傳的狀況下才會進行惟一文件名。不然將和分塊上傳的原理衝突,第1塊之後的文件流將沒法寫入正確的文件中。 if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
 $ext = strrpos($fileName, '.');
 $fileName_a = substr($fileName, 0, $ext);
 $fileName_b = substr($fileName, $ext);

 $count = 1;
 while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
  $count++;

 $fileName = $fileName_a . '_' . $count . $fileName_b;
}/*建立文件目錄*/ if (!file_exists($targetDir))
 @mkdir($targetDir);if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
 while (($file = readdir($dir)) !== false) {
  $filePath = $targetDir . DIRECTORY_SEPARATOR . $file;

  // Remove temp files if they are older than the max age   if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
   @unlink($filePath);
 }

 closedir($dir);
} else  die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
*/// 上傳寫文件步驟,這一部分如下的代碼可直接引用 if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
 $contentType = $_SERVER["HTTP_CONTENT_TYPE"];if (isset($_SERVER["CONTENT_TYPE"]))
 $contentType = $_SERVER["CONTENT_TYPE"];// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 if (strpos($contentType, "multipart") !== false) {
 if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
  // Open temp file   $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
  if ($out) {
   // Read binary input stream and append it to temp file    $in = fopen($_FILES['file']['tmp_name'], "rb");

   if ($in) {
    while ($buff = fread($in, 4096))
     fwrite($out, $buff);
   } else     die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
   fclose($in);
   fclose($out);
   @unlink($_FILES['file']['tmp_name']);
  } else    die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
 } else   die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
 // Open temp file  $out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
 if ($out) {
  // Read binary input stream and append it to temp file   $in = fopen("php://input", "rb");

  if ($in) {
   while ($buff = fread($in, 4096))
    fwrite($out, $buff);
  } else    die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');

  fclose($in);
  fclose($out);
 } else   die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}// Return JSON-RPC response die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');

?>

 

參考資料:

www.mwinds.net

www.plupload.com 

因爲該組件確實很強大,可是中文資料很是的少,因此發表這篇文章但願對你們有所幫助。之後將會陸續介紹plupload的其餘方面應用好比自定製上傳問題跟IE兼容問題。

相關文章
相關標籤/搜索