Extjs3 + swfUpload2.2 实现多文件上传控件

要在ExrtJS框架实现选择多文件上传,FileUploadField已经无法满足需求,所以采用了 swfUpload上传控件,上传窗口如下:

多选文件进行上传(其实是每个文件异步上传),可以中途停止文件上传,移除所选文件等操作。上传窗口代码如下:


var ctx = ‘<%=request.getContextPath()%>‘;
Ext.onReady(function(){
    Ext.QuickTips.init();
    new Ext.Window({
        width : 650,
        title : ‘选择目标文件上传‘,
        height : 300,
        layout : ‘fit‘,
        items : [
            {
                xtype:‘uploadPanel‘,
                border : false,
                fileSize : 1024*50,//限制文件大小kb
                uploadUrl : ctx+‘/uploadFiles.action‘,
                flashUrl : ctx+‘/swfupload.swf‘,//flash文件路径
                filePostName : ‘file‘, //后台接收参数名称
                fileTypes : ‘*.*‘,//可上传文件类型 *.doc
                postParams : {savePath:‘upload‘} //需要传到后台的参数
            }
        ]
    }).show();
});

构建完列表后 afterrender 监听函数添加flash生成文件选择窗口:

keel.UploadPanel.superclass.constructor.call(this,{
        tbar : [
            {text:‘添加文件‘,iconCls:‘add‘,ref:‘../addBtn‘},‘->‘,
            {text:‘上传‘,ref:‘../uploadBtn‘,iconCls:‘up‘,handler:this.startUpload,scope:this},‘-‘,
            {text:‘停止上传‘,ref:‘../stopBtn‘,iconCls:‘delete‘,handler:this.stopUpload,scope:this,disabled:true},‘-‘,
            {text:‘移除所有‘,ref:‘../deleteBtn‘,iconCls:‘delete2‘,handler:this.deleteAll,scope:this},‘-‘
        ],
        layout : ‘fit‘,
        items : [this.gp],
        listeners : {
            ‘afterrender‘:function(){
                var em = this.getTopToolbar().get(0).el.child(‘em‘);
                var placeHolderId = Ext.id();
                em.setStyle({
                    position : ‘relative‘,
                    display : ‘block‘
                });
                em.createChild({
                    tag : ‘div‘,
                    id : placeHolderId
                });
                this.swfupload = new SWFUpload(Ext.apply(this.setting,{
                    button_width : em.getWidth(),
                    button_height : em.getHeight(),
                    button_placeholder_id :placeHolderId
                }));
                this.swfupload.uploadStopped = false;
                Ext.get(this.swfupload.movieName).setStyle({
                    position : ‘absolute‘,
                    top : 0,
                    left : -2//此处需设置为0,否则flash偏右按钮失效
                });
            },
            scope : this,
            delay : 100
        }
    });

后台uploadFiles.action上传成功{"success":true},上传失败返回{"success":false},前台接收进行处理:

//文件上传成功后触发的事件处理函数 onUploadSuccess : function(file, serverData) {
        var me = this.customSettings.scope_handler;
        var ds = me.gp.store;
        if (Ext.util.JSON.decode(serverData).success) {
            for(var i=0;i<ds.getCount();i++){
                var rec =ds.getAt(i);
                if(rec.get(‘id‘)==file.id){
                    rec.set(‘state‘, file.filestatus);
                    rec.commit();
                }
            }
        }else{
            for(var i=0;i<ds.getCount();i++){
                var rec =ds.getAt(i);
                if(rec.get(‘id‘)==file.id){
                    rec.set(‘percent‘, 0);
                    rec.set(‘state‘, -3);
                    rec.commit();
                }
            }
        }
        me.linkBtnEvent();
    }

index.jsp 页面代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>swfUpload demo</title>
    <link rel="stylesheet" href="<%=request.getContextPath()%>/public/css/common.css" type="text/css" />
    <script type=‘text/javascript‘ src="<%=request.getContextPath()%>/public/ext/ext-base.js"></script>
    <script type=‘text/javascript‘ src="<%=request.getContextPath()%>/public/ext/ext-all.js"></script>
    <script type="text/javascript" src="<%=request.getContextPath()%>/public/ux/uploader/swfupload.js"></script>
    <script type="text/javascript" src="<%=request.getContextPath()%>/public/ux/uploader/uploaderPanel.js"></script>
  </head>

  <body>
  </body>
</html>

衷心感谢 http://czpae86.iteye.com/blog/834123?page=2#comments

-------------------------------华丽丽的分割线----------------------------------

满心欢喜的提交了代码,但测试那边同事反馈火狐浏览器无法上传,经过查找网上很多人遇到这种情况,原来是FireFox下使用swfUpload flash上传文件session丢失这个bug。由于项目后台做了登录用户权限控制,点击上传的时候验证未通过请求被抛弃,所以文件上传失败。

网上技术大拿有如下文章:

当页面需要使用 session 中的用户信息时,却无法在 Firefox 下使用它进行正常的文件上传。在 IE 下,上传工具能够工作,而一到 Firefox 下,SWFUpload 就会提示错误 302。通过从 Fiddler 抓包,发现上传文件的请求被 302 重定向到了登陆页面,所以无法正常上传文件。也就是说,之前用户登陆后的 session 信息在 Flash 发送的上传请求中丢失了。再一看请求的 header,当中没有可以用来标识当前 session ID 的 cookie 值(对于 J2EE 为 JSESSIONID,PHP 为 PHPSESSID 等)。这是什么原因呢?经过一番搜索,找到了 Adobe 官方的一篇文章,说道:

A FileReference.upload() currently does not use the same cookies as your browser session if you are using Firefox (on Windows). In such cases, cookie information has to be inserted manually. 

好吧,这个解释虽然很清楚地表明,Flash 在 Firefox 下进行文件上传不会使用浏览器 cookie 中的 session ID,但是貌似并没有回答文章标题当中的“为什么”,即为什么不使用和浏览器中的 session ID 来进行通信。

看来 cookie 是指望不上了,那只能像上面说的那样“手工”传递 session ID 了。于是我们可以在 URL 中拼接一个如 ";jsessionid=blahblah" 的字符串(注意要拼在路径之后,参数之前),像下面这样:

uploadUrl : ‘http://example.com/app;jsessionid=blahblah‘

Servlet 规范 7.1.3 节中的规定,当客户端不接受 cookie 时,Servlet 容器应当能解析出这类 URL 中的 JSESSIONID,来维持当前 session 的状态。其他服务器端环境中也有类似的机制。于是我们对文件上传功能做了一定的修改:在用户进入上传页面时,就把当前的 session ID 写到页面中,作为 JavaScript 变量拼接到 SWFUpload 上传文件的目标 URL 中,Flash 就可以利用我们人工传入的 JSESSIONID 来维持登陆状态了。当开始上传时,Flash 通过自己的连接通道向服务器发送数据,但是因为请求的路径中包含了 session 信息所以可以和浏览器的 session 状态保持同步,服务器可以通过 URL 中的 session ID 来获取用户登录的信息。

于是,302 错误被解决了,看起来一切都 OK 了。可是,不久我们又发现了新的问题:当用户打开上传页面后较长时间没有操作,服务器端的 session 超时了,这个时候进行文件的上传用的还是超时的那个 session ID,所以会失败也是应该的。但是当这个时候用户重新进行了登录,再次进入上传页面上传,却仍然会失败,只有重新启动浏览器才能再次进行上传。这是为什么 呢?从服务器端错误来看,还是用户的登陆信息丢失的问题,也就是说,Flash 在上传文件时,还是没能将用户进行过登陆的这个 session ID 成功传递给服务器端。通过在 Fiddler 中抓包分析,终于找到了原因。

文章来源http://lync.in/session-trap-on-uploading-files-using-flash-in-firefox/

这个方法可以解决大部分网友遇到seesion丢失的问题,但我的项目里调用的是jsf的统一登录接口,没有得到产生的一级域名cookie,按照这种解决方式上传请求还是会被抛弃,焦头烂额的搞了几个小时,突然想到让上传的方法不被Interceptor拦截不就解决了吗,山重水复疑无路,最后在拦截器配置文件里修改一下:

exclude.path=/common/uploadFiles.do,/common/uploadImgs.do

经过这样的一个过程基本上实现了多文件上传的功能,适用于后台上传文件的代码没有用到seesion这情况。

时间: 2024-10-27 15:26:48

Extjs3 + swfUpload2.2 实现多文件上传控件的相关文章

如何清空文件上传控件里的选定文件(路径)

我又来扯鸡毛蒜皮了.有名言曰人生短得不够扯鸡毛蒜皮,但我的工作就是由无数的鸡毛蒜皮组成,如之奈何? 今天的鸡毛和蒜皮是:如何清空文件上传控件里的选定文件(路径)? 场景是酱紫的: 有一个上传控件和一个按钮,其中上传控件隐藏.点击按钮,触发上传控件点击事件,于是弹出文件选择对话框:选好文件后,于是触发了上传控件的onchange事件.在这个事件里,将文件上传. 有点装逼,就是隐藏了上传控件.这可能是出于界面简约的考虑.问题是,同一个文件不能连续上传2次,因为路径不变,没有触发onchange事件.

在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件

在WebBrowser中通过模拟键盘鼠标操控网页中的文件上传控件 引言 这两天沉迷了Google SketchUp,刚刚玩够,一时兴起,研究了一下WebBrowser. 我在<WebBrowser控件使用技巧分享>一文中曾谈到过"我现在可以通过WebBrowser实现对各种Html元素的操控,唯独无法控制Html的上传控件",出于安全原因,IE没有对上传控件提供操控支持,这使得我们没法像控制其他控件一样用简单的代码进行赋值. 比较实际的解决方案就是模拟操作了,下面我就将演示

ASP.NET使用文件上传控件上传图片

ASPX代码 <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xht

改变FileUpload文件上传控件的显示方式,确认后上传

一.Aspx页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUploadDemo.aspx.cs" Inherits="WebApplication1.FileUploadDemo" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu

jquery文件上传控件 Uploadify

(转自 http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html) 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,删除已上传文件. 要求使用jquery1.4或以上版本,flash player 9.0.24以上. 有两个版本,一个用flash,一个是html5.html5的需要付费~所以这里只说flash版本的用法. 官网:http://www.uploadify.com/ 控件截图

怎样清空文件上传控件里的选定文件(路径)

我又来扯鸡毛蒜皮了. 有名言曰人生短得不够扯鸡毛蒜皮,但我的工作就是由无数的鸡毛蒜皮组成,如之奈何? 今天的鸡毛和蒜皮是:怎样清空文件上传控件里的选定文件(路径)? 场景是酱紫的: 有一个上传控件和一个button.当中上传控件隐藏.点击button,触发上传控件点击事件,于是弹出文件选择对话框:选好文件后.于是触发了上传控件的onchange事件.在这个事件里.将文件上传. 有点装逼,就是隐藏了上传控件. 这可能是出于界面简约的考虑.问题是.同一个文件不能连续上传2次.由于路径不变,没有触发o

文件上传控件值发生变化后自动提交表单

当文件上传控件发生变化后自动提交表单,首先在页面加载完成后注册change事件,然后检测到值得变化后提交上传代码,代码备忘. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> window.

.Net 使用文件上传控件FileUpload上传图片

例1: 来源:http://long546324.iteye.com/blog/349946 Default.aspx文档: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1

因用了NeatUpload大文件上传控件而导致Nonfile portion &gt; 4194304 bytes错误的解决方法

今天遇到一个问题,就是"NeatUpload大文件上传控件而导致Nonfile portion > 4194304 bytes错误",百度后发现了一个解决方法,跟大家分享下: NeatUpload是一个开源的大文件上传控件,非常的强大,支持文件类型过滤.上传进度条显示.多文件上传等强大的功能. 但部署至项目后,有些地方用普通的FileUpload上传时却发生了一个错误(Nonfile portion > 4194304 bytes,文件大于默认值4M),因如果用NeatUp