zoukankan      html  css  js  c++  java
  • flash 多个文件上传

    引用:http://bbs.51aspx.com/showtopic-44723.html

    像flickr一样多选图片一次上传

    做上传图片功能的时候,经常会遇到这样一个问题,有时候可能需要一次上传多张图片,而用html中默认的上控件,却只能选定一个文件,且不能对文件的后缀进行筛选。需要一次上传多个文件的需求,往往可以通过添加多个上传控件来予以满足,比如百度空间的相册上传功能就是这样来实现的。不过,要实现对上传文件后缀的过滤,却始终无法通过常规的方法予以实现。

    这两个功能真的这么难以实现吗?非也,看看flickr的上传功能即可获得明确的答复。

    为什么能实现这样的功能呢?google了一下,谜底就揭晓了。原来,这是利用了flash的若干功能,通过javascript和actionscript的交互得以实现的。js和as的通讯以前有研究过,所以要实现起来非常简单。再到flash里边f1一下,关于上传方面的相关只是也差不多了解了,因此,接下来的事情的就只是顺水推舟的事情了。
    最重要的还是flash代码的完善,最后的成果如下:

    // MultiUploader.fla
    import flash.net.FileReferenceList;
    import flash.net.FileReference;
    import flash.external.ExternalInterface;

    // 设置as中函数和js调用时的映射关系
    ExternalInterface.addCallback("fu_open_dialog", null, openDialog);
    ExternalInterface.addCallback("fu_begin_upload", null, beginUpload);

    // 可以通过html页面里边设置FlashVars里边的upload_url来更改上传文件的路径
    var uploadUrl:String = typeof(_root.upload_url) == "undefined" ? "FlashUpload.ashx" : _root.upload_url;
    var listener:Object = new Object();
    // 选择文件后,会视图调用js函数onUploaderSelect,并将文件列表传入进去,便于js进一步做一些逻辑控制
    listener.onSelect = function(fileRefList:FileReferenceList) {
      ExternalInterface.call("onUploaderSelect", fileRefList.fileList);  
    };

    var fileRefList:FileReferenceList = null;
    var imageTypes:Object = new Object();
    imageTypes.description = "Images (*.jpg, *.jpeg, *.gif, *.png)"; // 上传文件类型说明
    imageTypes.extension = "*.jpg; *.jpeg; *.gif; *.png"; // 控制上传文件类型

    // 显示文件打开窗口
    function openDialog():Void {
      if (fileRefList == null) {
      fileRefList = new FileReferenceList();
      fileRefList.addListener(listener);
      }
      fileRefList.browse([imageTypes]);
    }
    // 开始上传
    function beginUpload():Void {
      var lis = new Object();
      // 每上传完一个文件后调用js函数onUploaderComplete
      lis.onComplete = function(file:FileReference):Void {
      ExternalInterface.call("onUploaderComplete", file.name);  
      };
      // 处理上传地址的http状态错误。比如404等。
      lis.onHTTPError = function(file:FileReference, httpError: Number):Void {
      ExternalInterface.call("onUploaderHTTPError", httpError, file.name);
      }
        
      var list:Array = fileRefList.fileList;
      var item:FileReference;
      // 最终还是将文件分单次传到指定上传页面进行处理
      for(var i:Number = 0; i < list.length; i++) {
      item = list;
      item.addListener(lis);
      item.upload(uploadUrl);
      }
    }

    至于客户端的处理,只需要将as中自动调用的几个js函数实现即可。最后的页面代码如下:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <input type="button" value="open" onclick="openUploadDialog();"/>
    <input type="button" value="upload" onclick="uploadFiles();"/>

    <div id="flashPanel"></div>

    </body>
    <script type="text/javascript">
    var flash = createUploadFlash(document.getElementById('flashPanel'), 'upload.swf', 'FlashUpload.ashx')
    // 打开文件对话框
    function openUploadDialog() {
      flash.fu_open_dialog();
    }
    // 上传文件
    function uploadFiles() {
      flash.fu_begin_upload();
    }

    // 选择文件以后
    function onUploaderSelect(list) {
      alert(list);
    }

    // 上传完一个文件以后
    function onUploaderComplete(name) {
      alert(name);   
    }

    // 上传文件出错时
    function onUploaderHTTPError(number, name) {
      switch (number) {
      case 413:
      alert("文件" + name + "大于10K,不能上传");
      break;   
      }
    }
    /**
    * 创建一个flash。主要是在ie7里边需要用鼠标点击才能激活flash,通过动态生成flash的方式可以绕过这一点。
    * @param panel 用来放置flash的div
    * @param flashUrl flash的地址
    * @param uploadUrl 用来出来上传文件的地址
    */
    function createUploadFlash(panel, flashUrl, uploadUrl){
      var code = '<object classid="clsid27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="0" height="0" id="flashObject" align="middle">\
      <param name="allowScriptAccess" value="sameDomain" />\
      <param name="movie" value="' + flashUrl + '" />\
      <param name="quality" value="high" />\
      <param name="bgcolor" value="#ffffff" />\
      <param name="FlashVars" value="upload_url=' + uploadUrl + '" />\
      <embed src="' + flashUrl + '" quality="high" bgcolor="#ffffff" width="0" height="0" name="flashObject" FlashVars="upload_url=' + uploadUrl + '" align="middle" allowScriptAccess="sameDomain" id="flashObject" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />\
      </object>';
      panel.innerHTML = code;
      return window.document.flashObject;
    }

    </script>
    </html>
    这次功能的实现上,在其他方面都还很顺利得以实现,反而是在createUploadFlash这个函数的实现上遇到了一些麻烦。因为最后返回flash对象的时候经常不被正常地识别。如果这段代码不用js生成,那么用document.flashObject和dobument.getElementById('flashObject')都可以正常识别flashObject,但动态生成以后,用后者就不能正常被访问到了,可能的原因是加载需要一定的延时,有待研究。

  • 相关阅读:
    JS站点
    1011 World Cup Betting (20分)
    1007 Maximum Subsequence Sum (25分)(动态规划DP)
    1006 Sign In and Sign Out (25分)
    1005 Spell It Right (20分)
    1004 Counting Leaves (30分)(DFS)
    1003 Emergency (25分)(Dijkstra算法)
    1002 A+B for Polynomials (25分)
    1001 A+B Format (20分)
    canvas
  • 原文地址:https://www.cnblogs.com/sode/p/2834165.html
Copyright © 2011-2022 走看看