日期:2014-05-16  浏览次数:20409 次

PandaJS 使用说明 (1.3): 文件上传与下载
PandaJS 使用说明 (1.3): 文件上传与下载

  PanadaJS 为文件上传与下载提供了服务器端和客户端的组件,客户端 JS 可以根据浏览器的支持情况,自动选择 HTML5,Flash 和传统(隐藏)表单上传;服务器端兼容 HTML5 Streaming 方式上传和 Multipart 方式上传。
  接下来,就让我们在上一篇文章编写的 hello.html 上直接添加增加一个文件上传按钮吧。

运行效果

  三种上传方式外观相似,如下图所示:


  直接在前一篇文章中使用的 hello.html 中增加了上传按钮。点击上传按钮弹出文件选择框(HTML 或 Flash 方式支持文件多选),选择完成后立即开始上传。上传过程中显示上传进度,期间可以取消;完成后添加到下方的完成列表中,可以移除已经上传完成的文件。
  HTML5 和 表单上传的样式通过 CSS 样式进行设置,Flash 按钮需要加载一张图片(如附件中的 panda.button.png),可以在创建组件的参数中设置样式。

  同时,对于支持 HTML5 的浏览器,还支持拖拽文件进行上传。
  拖拽效果如下:


  只有支持 HTML5 方式的浏览器才提供拖拽功能,如较新版本的 Chrome,FireFox 等;
  Safari 上的拖拽区域不会显示出来(因为没法 drop 到一个 div 上,谁有解决的办法吗?),需要拖拽到上传按钮上,并且同时拖拽多个文件到上传按钮时,也只上传一个文件(这是 Safari 的一个 Bug,有办法解决吗?)。
  点击文件名称进行下载:


HTML 页面修改


  首先,需要在这句代码:
<div id="message" /></div>
  的后面添加一个文件上传按钮:
<div id="file-uploader"></div>

  然后,增加显示已上传的附件的名称的 div:
<div id="attachment_names"></div>

	<script id="attachment_names_tmpl" type="tmpl">
		<span id="attachment_${file.id}" class="attachment_name">
			<a href="##" name="${data.name}">${panda.shorten(file.name, 11)}</a> (${panda.formatSize(file.size)})
			<a href="##" class="remove" title="Remove">&nbsp;</a>
		</span>
	</script>

  最后,需要在以下代码:
<script src="js/lib/panda.js"></script>
  的后面增加对 panda.uploader.js 的引用。
<script src="js/lib/panda.uploader.js"></script>


  HTML 页面的修改就这些了,接着让我们看看 JS 代码的修改。

客户端 JS 修改

  在 webapp/js/hello.js 中,需要增加如下代码,以初始化一个文件上传按钮:
	panda.uploader({
		// 指定文件上传按钮所在的div
		element: $("#file-uploader")[0],
		// 指定处理请求的方法
		params: { action: "hello.upload" },
		// 文件大小限制
		sizeLimit: 1000 * 1024 * 1024,
		// 上传结束的处理
		onComplete: function(file, data){
			// 上传结束,显示文件名称
			$("#attachment_names").append($("#attachment_names_tmpl").tmpl({
				file: file, data: data
			}));

			// 增加文件名称的点击事件
			var $attachment = $("#attachment_" + file.id);
			var $a = $attachment.find("a");

			// 点击文件名称,开始下载文件
			$a.eq(0).click(function() {
				panda.open({
					action: "hello.download",
					params: { name: $(this).attr("name") }
				});
			});

			// 点击 Remove 按钮,删除已上传的附件
			$a.eq(1).click(function(){ $attachment.remove(); });
		}
	});

引用
  0.0.3 版本将客户端的 panada.upload(...) 重命名为 panda.uploader(...),以避免与服务器端的 panda.upload(...) 重名。



服务器端 JS 修改

  在 scripts/api/hello.js 中增加如下代码,以处理文件上传与下载的请求:
	// 文件上传
	upload: function(params, req) {
		// 检查文件大小
		var size = parseFloat(req.getHeader("Content-Length"));
		
		if (!size || size <= 0 ) {
			throw "Invalid Content-Length";
		} else if (size > 1000 * 1024 * 1024) {
			throw "File too large.";
		}

		// 生成文件名称
		var prefix = new Date().getTime() + "-"