[分享]Plupload多文件上传开发利器(部分中文注释)

2014-09-22Javascript5422

Plupload 是由 TinyMCE 开发者分享的上传元件,它混合使用多种网页开发技术,如 HTML5 Gears, Silverlight, Flash, BrowserPlus,如果浏览器支持这些功能的其中一项,就可以提供完整丰富的多文件同时上传机制;如果很不幸浏览器(至少支持flash吧)什么都不支持,它仍会使用最原始的 HTML 表单进行上传。

官方网站: http://www.plupload.com/

Plupload 是开源的,位于 GitHub: https://github.com/moxiecode/plupload

Plupload支持技术:

1:Flash

2:Gears

3:HTML 5

4:Silverlight

5:BrowserPlus

6:HTML 4

plupload主要功能:

1:突破HTTP上传限制,可上传大文件,官方论坛中有讨论上传2G文件的应用。

2:多文件队列上传

3:图片自动生成缩略图

4:上传后自动生成唯一文件名

5:自定制UI


[分享]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"}');
?>


分享:

支付宝

微信