热烈祝贺台州维博网络的站长论坛隆重上线!(2012-05-28)    热烈庆祝伟大的祖国60周年生日 点击进来我们一起为她祝福吧(2009-09-26)    站长论坛禁止发布广告,一经发现立即删除。谢谢各位合作!.(2009-08-08)    热烈祝贺台州网址导航全面升级,全新版本上线!希望各位一如既往地支持台州网址导航的发展.(2009-03-28)    台州站长论坛恭祝各位新年快乐,牛年行大运!(2009-01-24)    台州Link正式更名为台州网址导航,专业做以台州网址为主的网址导航!(2008-05-23)    热烈祝贺台州Link资讯改名为中国站长资讯!希望在以后日子里得到大家的大力支持和帮助!(2008-04-10)    热烈祝贺台州Link论坛改名为台州站长论坛!希望大家继续支持和鼓励!(2008-04-10)    台州站长论坛原[社会琐碎]版块更名为[生活百科]版块!(2007-09-05)    特此通知:新台州站长论坛的数据信息全部升级成功!">特此通知:新台州站长论坛的数据信息全部升级成功!(2007-09-01)    台州站长论坛对未通过验证的会员进行合理的清除,请您谅解(2007-08-30)    台州网址导航|上网导航诚邀世界各地的网站友情链接和友谊联盟,共同引领网站导航、前进!(2007-08-30)    禁止发广告之类的帖,已发现立即删除!(2007-08-30)    希望各位上传与下载有用资源和最新信息(2007-08-30)    热烈祝贺台州站长论坛全面升级成功,全新上线!(2007-08-30)    
便民网址导航,轻松网上冲浪。
台州维博网络专业开发网站门户平台系统
您当前的位置: 首页 » PHP/Perl编程 » PHP+Flash多文件异步上传swfupload

PHP+Flash多文件异步上传swfupload

论坛链接
  • PHP+Flash多文件异步上传swfupload
  • 发布时间:2010-03-31 16:36:02    浏览数:20839    发布者:sunhw0725    设置字体【   
什么是SWFUpload?
  SWFUpload是一个客户端文件上传工具,最初由Vinterwebb.se开发,它通过整合Flash与JavaScript技术为WEB开发者提供了一个具有丰富功能继而超越传统<input type="file" />标签的文件上传模式。官方地址:http://www.swfupload.org

SWFUpload的主要特点
  * 可以同时上传多个文件;
  * 类似AJAX的无刷新上传;
  * 可以显示上传进度;
  * 良好的浏览器兼容性;
  * 兼容其他JavaScript库 (例如:jQuery, Prototype等);
  * 支持Flash 8和Flash 9;
  SWFUpload不同于其他基于Flash构建的上传工具,它有着优雅的代码设计,开发者可以利用XHTML、CSS和JavaScript来随心所欲的定制它在浏览器下的外观;它还提供了一组简明的JavaScript事件,借助它们开发者可以方便的在文件上传过程中更新页面内容来营造各种动态效果。
  在使用SWFUpload之前,请确认你具备一定的JavaScript和DOM知识。在实际开发中,大部分的错误都是由于错误的设置和低劣的Event Handlers处理程序所造成的。

文档中文翻译
  http://www.v-sky.com/doc/swfupload/v2.1.0/Documentation.html

效果演示
  * Classic Form Demo http://demo.swfupload.org/formsdemo ;
  * Features Demo http://demo.swfupload.org/featuresdemo ;
  * Application Demo http://demo.swfupload.org/applicationdemo ;
  * v1.0.2 Plugin Demo http://demo.swfupload.org/v102demo ;

选择合适的Flash控件
  在发行包(SWFUpload v2)中含有2个版本的Flash控件(swfupload_f8.swf 与wfupload_f9.swf),其中第一个版本拥有最佳的兼容性,但是为此损失了部分功能;而第二个版本提供了一些附加的功能但是损失了兼容性。

SWFUpload的初始化与配置
  首先,在页面中引用SWFUpload.js ,如
  <script type="text/javascript" src="http://www.swfupload.org/swfupload.js"></script>
  然后,初始化SWFUpload ,如
  var swfu;
  window.onload = function () {
  swfu = new SWFUpload({
  upload_url : "http://www.swfupload.org/upload.php",
  flash_url : "http://www.swfupload.org/swfupload_f9.swf", file_size_limit : "20480"
  });
  };
  以下是一个标准的SWFUpload初始化设置所需的参数,你可以根据需要自己进行删减:
  {
  upload_url : "http://www.swfupload.org/upload.php", 处理上传请求的服务器端脚本URL
  file_post_name : "Filedata", 是POST过去的$_FILES的数组名
  post_params : {
  "post_param_name_1" : "post_param_value_1",
  "post_param_name_2" : "post_param_value_2",
  "post_param_name_n" : "post_param_value_n"
  },
  file_types : "*.jpg;*.gif", 允许上传的文件类型
  file_types_description: "Web Image Files", 文件类型描述
  file_size_limit : "1024", 上传文件体积上限,单位MB
  file_upload_limit : 10, 限定用户一次性最多上传多少个文件,在上传过程中,该数字会累加,如果设置为“0”,则表示没有限制
  file_queue_limit : 2, 上传队列数量限制,该项通常不需设置,会根据file_upload_limit自动赋值
  flash_url : "http://www.swfupload.org/swfupload_f9.swf", Flash控件的URL
  flash_width : "1px",
  flash_height : "1px",
  flash_color : "#FFFFFF",
  debug : false, 是否显示调试信息
  swfupload_loaded_handler : swfupload_loaded_function, 当Flash控件成功加载后触发的事件处理函数
  file_dialog_start_handler : file_dialog_start_function, 当文件选取对话框弹出前出发的事件处理函数
  file_queued_handler : file_queued_function,
  file_queue_error_handler : file_queue_error_function,
  file_dialog_complete_handler : file_dialog_complete_function, 当文件选取对话框关闭后触发的事件处理函数
  upload_start_handler : upload_start_function, 开始上传文件前触发的事件处理函数
  upload_progress_handler : upload_progress_function,
  upload_error_handler : upload_error_function,
  upload_success_handler : upload_success_function, 文件上传成功后触发的事件处理函数
  upload_complete_handler : upload_complete_function,
  debug_handler : debug_function,
  custom_settings : { 自定义设置
  custom_setting_1 : "custom_setting_value_1",
  custom_setting_2 : "custom_setting_value_2",
  custom_setting_n : "custom_setting_value_n",
  }
  }
SWFUpload中的File Object
  在SWFUpload的使用过程中,无论在客户端还是服务器端都要和File Object打交道,在一个File Object中包含了以下内容:
  {
  id : string, // SWFUpload file id, used for starting or cancelling and upload
  index : number, // The index of this file for use in getFile(i)
  name : string, // The file name. The path is not included.
  size : number, // The file size in bytes
  type : string, // The file type as reported by the client operating system
  creationdate : Date, // The date the file was created
  modificationdate : Date, // The date the file was last modified
  filestatus : number, // The file's current status. Use SWFUpload.FILE_STATUS to interpret the value.
  }
SWFUpload中的方法
  + setPostParams (param_object)
  - 描述
  动态修改SWFUpload初始化设置中的post_params属性,其中所有的值都将被覆盖。
  - 参数
  param_object:一个simple JavaScript object,所有的name/value都必须是字符串,例如(this.setPostParams({ "Mari": name });)。
  - 返回
  void
SWFUpload中的事件
  SWFUpload在运行过程中提供了多种事件,这些事件可以让开发者借助句柄来改变页面UI、改变行为,或者报告错误。所有这些事件都可以在一个SWFUpload实体中被调用,这意味着在这些事件对应的函数中,你可以用 this 关键字来代替引用SWFUpload实体。
  + fileDialogComplete (number of files selected)
  - 触发条件
  1. 用户选择好了要上传文件,并关闭对话框;
  2. 用户什么也没选,并取消对话框;
  如果你希望在用户选择完文件后自动开始上传操作,那么可以将 this.startUpload() 操作放在这里。
  - 传入参数
  number of files selected:将返回用户所选取的文件个数。
  + uploadStart (file object)
  - 触发条件
  该事件在文件上传之前触发,它用于完成一些准备工作,比如传递参数;负责响应该事件的句柄函数可以有2个返回值(true 或 false)当返回值为false时,整个上传将被取消;当返回值为true时上传过程继续进行。而如果返回值为false,则通常是由一个uploadError事件所导致的。
  注:官方帮助文档的原文中对该事件的描述中有这样一句:“If you return 'true' or do not return any value then the upload proceeds.”,从中可以看到既定的设计是当不返回任何值的时候应该等同于返回true,但是笔者在开发中发现必须明确返回值,否则上传进程将停止响应,不知是否是一个bug呢?
  - 传入参数
  file object:文件对象
  + uploadComplete (file object)
  - 触发条件
  在完成一个上传周期后(在uploadError 或 uploadSuccess之后),此时一个上传操作已经结束,另一个上传操作可以开始了。
  - 传入参数
  file object:文件对象
  + uploadProgress (file object, bytes complete, total bytes)
  - 触发条件
  该事件在整个文件的上传过程中定期性的被Flash控件自动触发,用以帮助开发者实时更新页面UI来制作上传进度条。
  注意:该事件在Linux版本的Flash Player中存在问题,目前还无法解决。
  - 传入参数
  file object:文件对象
  bytes complete:已经上传完毕的文件字节数
  total bytes:文件总体积的字节数
常见错误
  ■ 所上传的文件体积并未超出SWFUpload所设置的数值,但为何无法成功上传?
  □ 通常这是由于服务器端的限制所造成的,以Apache+PHP为例,请修改php.ini中的post_max_size与upload_max_filesize两项设置。
  ■ 在带有Session验证的网站后台中SWFUpload无法正常工作?
  □ 这是因为SWFUpload在上传时相当于重新开辟了一个新的Session进程,因此无法与原有程序的Session保持一致,这就需要在上传时传递原有程序的SessionID,根据它来“找回”其应有的Session。
  ■ 关于swfupload上传中文文件名乱码的问题
  □ 实际上是由于编码的问题造成的,程序使用的utf-8,文件名传递时也是这种编码,因此造成乱码或文件不能保存,仅是需要修改接收文件,以PHP为例,upload.php中
  $file_name = $_FILES[$upload_name]['name'];
  $file_name=iconv("UTF-8","GB2312",$file_name);
  这样即可解决。
      swfUpload注意事项

在使用swfupload上传文件的时候,老是绕不过登录验证。查了一下GOOGLe,没查到,问了百度,他告诉我答案:

swfuplaod在上传时,会新开一个进程,和原来的进程不一致,要解决这个问题,需要指定session_id,然后在登录页面判断,如果有post过来的session_id,那么就用函数session_id( $_POST['PHP_SESSIONID'])指定一下。

上传页的JS里面,可以获取当前的SESSION_ID的。

例如上传页的JS中:

post_params: {"PHPSESSID": "<?php echo session_id(); ?>"},

在验证的判断页中:

if (isset($_POST["PHPSESSID"])) {
session_id($_POST["PHPSESSID"]);
}

(这一段是网上的注释:在带有Session验证的网站后台中SWFUpload无法正常工作,这是因为SWFUpload在上传时相当于重新开辟了一个新的Session 进程,因此无法与原有程序的Session保持一致,这就需要在上传时传递原有程序的SessionID,根据它来“找回”其应有的Session。)
      由于项目需要,这两天研究了一下SWFUpload,一个JS和AS结合实现的上传“功能包”,简单来说原理就是利用flash的FileReference类在客户端完成文件信息的过滤,包括类型、大小,以及上传的实时进度信息,然后利用externalInterface来跟客户端的JS通信,提供了一系列属性、方法和事件触发时的回调函数接口,将UI的主动权完全由FLASH转交给了JS来操作。(PS:目前版本还没有Release,有些功能和文档还不全,疑惑之处可直接翻代码看看。等我项目结束时希望SWFUpload放出正式版和官方确定的接口文档了,到时再针对传统文件上传的各种方式和SWFUpload功能包唠叨几句。)这里只唠叨一下目前这个版本存在的一个BUG,在IE6内核的多标签浏览器中(例如GreenBrowser和Maxthon),一旦页面刷新过后,SWFUpload的功能就不正常了,或许你也正为这个发愁了,可以先跳到这里察看临时解决方案。

  最初用SWFUpload做demo的时候就发现了目前存在一个小BUG:我机器上的浏览器环境是GreenBrowser(IE6内核),打开上传页面,一切功能都正常,此时如果刷新或者强刷一下页面,那么当点击文件浏览按钮时(触发selectFile事件),debug信息中就会提示“Could not find Flash element”,而在FF、IE7下面功能很正常,更奇怪的是在我随后的debug过程中我发现在单独的IE6,也就是系统提供的那个单窗口的IE6下居然功能也很正常。后来又在ie6内核下测试了maxthon同样存在和GreenBrowser一样的问题,难道这个跟多标签浏览器也有关系?第一反应是我的demo有问题。于是去SWFUpload的官方demo验证了下,发现居然也存在这个问题。哎~又是IE惹的祸。开始Debug之旅吧。

  一、首先用DOM察看器在IE下看看刷新前后DOM元素中flash元素的变化
  有了FireBug以后,让IE下的几个调试工具显得太简陋了,不过至少我还可以直接察看到DOM元素的变化。奇怪的是刷新前后,FLASH元素都完整地出现在DOM中,那为何会提示“Could not find Flash element”呢?
  
  二、 跟踪文件浏览的点击事件selectFile
  到SWFUpload库中能看到扩展了一个selectFile的方法。



SWFUpload.prototype.selectFile = function () {
var movie_element = this.getMovieElement();
if (movie_element !== null && typeof(movie_element.SelectFile) === "function") {
try {
movie_element.SelectFile();
}
catch (ex) {
this.debug("Could not call SelectFile: " + ex);
}
} else {
this.debug("Could not find Flash element");
}

};

SWFUpload.prototype.selectFile = function () {
var movie_element = this.getMovieElement();
if (movie_element !== null && typeof(movie_element.SelectFile) === "function") {
try {
movie_element.SelectFile();
}
catch (ex) {
this.debug("Could not call SelectFile: " + ex);
}
} else {
this.debug("Could not find Flash element");
}

};  难道“Could not find Flash element”是这里输出来的?于是将这个语句给注释掉再测试,果然没有看到“没有找到flash元素”的debug信息了,这就确定了是这个方法里出现了异常,仔细看了下这个if判断,这里不但对flash元素的存在性做了判断,还需要判断flash元素里是否存在SelectFile方法。个人觉得这个双保险检测是没有错,但这个debug信息未免就太笼统了,typeof(movie_element.SelectFile) === "function" 如果是false那也不能说明是flash元素不存在。之前我总结flash和js通信的时候也做过externalInterface的demo,猜测一下这里的实现原理:SelectFile方法是externalInterface类用addCallback方法在 flash中将一个名为SelectFile的方法注册到容器中可供JS调用,也就是现在看到的这种形式movie_element.SelectFile()。那么理论上如果flash元素存在,那么typeof(movie_element.SelectFile) === "function"肯定是true,可是在IE6这个总是很另类但又是用户占有率最高的浏览器里这个理论还真就出问题了,下面可以来证明一下。

  三、观察浏览器刷新前后movie_element.SelectFile的变化
  重新打开一个新页面测试SWFUpload的官方demo,测试文件浏览功能,正常。于是在地址栏输入

javascript:alert(document.getElementById("SWFUpload_0").SelectFile);void 0;

javascript:alert(document.getElementById("SWFUpload_0").SelectFile);void 0;

(PS:IE下的调试方法实在是太简陋了,还好广大开发者的智慧是无穷的。)
这里的SWFUpload_0是SWFUpload生成的flash元素时指定的id,这个可以从dom节点中看到。如果你想更详细地确认其中细节可以看SWFUpload中的initSWFUpload方法,事实上这里会有一个实例队列,因为这个demo中就是一个实例,所以这个flash的id在队列中是SWFUpload_0。回车执行上面的JS,正常情况下你会看到如下信息:

function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); }

function () { return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>")); }

  从这段代码的特征上也验证我之前的猜测,SelectFile确实是flash中注册的一个方法。
然后刷新此页面,再到地址栏输入回车,HOHO你会得到undefined信息。SWFUpload的开发者可能也没有想到理论上很保险的做法到IE6下会有如此怪异的行为。Flash还存在,为什么其中addCallback注册的方法会“消失”呢?难道是externalInterface类本身有问题?于是又把自己以前的一个demo拿出来测试,发现刷新前后功能依然很正常,匪夷所思。仔细对比了下两个demo的差异,最后将疑点锁定在了flash的写入方式,SWFUpload是用JS将flash写入到dom中的,我自己的demo中flash元素是直接写死在HTML代码里的。

  四、测试不同的flash写入方式对addCallback方法的影响
  AW说SWFUpload中写入flash的方法是从SWFObject库里抽出来的,这个SWFObject的官方说明也证实了这点。打开SWFUpload库确实也可以看到SWFObject的几个核心方法。那这就确定了SWFUpload写入flash和SWFObject原理上一样的,于是采用SWFobject对我之前的demo做测试。
  1、首先用最原始的方法将flash静态写入到页面中(察看实例)
  关于静态插入flash到页面的不同方式的细节以及他们对JS造成的影响随后再写个详细的东东,这里先不做具体探讨,暂且使用最常用的object和embed混合的方式。
  第一个按钮是js调用as中注册的say方法;
  第二个按钮是测试flash元素是否在页面中,如果在页面中,那么打印出他的innerHTML属性;
  第三个按钮是测试flash元素中addCallBack注册的方法是否还存在,如果存在那么将其打印出来;
  当页面第一次打开的时候分别点击三个按钮,callback注册的say方法呼叫正常,flash元素存在,其中注册的say方法也存在。
  下面将页面刷新一次再测试,测试结论和刚才一样,都很正常。这就确保了我目前采用的flash中addCallBack注册的say方法功能是正常的。

  2、利用SWFObject写入flash到页面中(察看实例)
  同样测试刷新前后的变化,刷新前功能正常,而将页面刷新一次再测试,就跟我之前描述的bug一样,怪异现象出现了,callback注册的say方法呼叫失败了,flash元素是存在的,但其中注册的say方法也不见了。
到这步为止已经找到办法解决项目中遇到的SWFUpload的刷新BUG了,将SWFUpload中写入flash的方法变成静态写入即可,事实上当时考虑项目进度我确实是这么做的,嘿嘿,尽管方法太笨。由于SWFUpload实例有很多设置需要配置到FlashVars中,所以做这个静态写入时最好先将SWFupload的getFlashHTML方法返回值打印出来(PS:需要针对IE和之外的浏览器,实际上就是Object和embed两种不同flash的插入方式做一个判断输出,切忌不能将他们同时写入页面,否则会造成SWFUpload无法正确找到实例的flash元素。)

  上面的解决方案只是曲线救国,考虑到以后项目中的灵活使用和维护,还是需要把其中的问题找出来,再回到我们的Debug进程来。现在已经证明问题出在flash的写入方式上。刨开SWFObject的代码能够很清晰看出它的原理:根据实例化时的最基本参数配置和属性、flashvars设置方法来针对object和embed两种不同的插入方法构造出两个不同的flashDom节点。当write方法调用时,将此节点写入到目标容器的innerHTML中。难道是innerHTML在作怪?

  五、跟踪innerHTML写入flash节点
  还是针对上面的demo做测试,将SWFObject调用write前构造出来的flash节点字符串和write之后浏览器里flash节点的html代码分别打印出来比较。

IE6:
Write调用前:
<object id="demo" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="300" height="100" style="undefined"><param name="movie" value="demo.swf" /><param name="bgcolor" value="#fff" /><param name="quality" value="high" /></object>

Write调用后:
<OBJECT id=demo height=100 width=300 classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000><PARAM NAME="_cx" VALUE="7938"><PARAM NAME="_cy" VALUE="2646"><PARAM NAME="FlashVars" VALUE=""><PARAM NAME="Movie" VALUE="demo.swf"><PARAM NAME="Src" VALUE="demo.swf"><PARAM NAME="WMode" VALUE="Window"><PARAM NAME="Play" VALUE="0"><PARAM NAME="Loop" VALUE="-1"><PARAM NAME="Quality" VALUE="High"><PARAM NAME="SAlign" VALUE=""><PARAM NAME="Menu" VALUE="-1"><PARAM NAME="Base" VALUE=""><PARAM NAME="AllowScriptAccess" VALUE=""><PARAM NAME="Scale" VALUE="ShowAll"><PARAM NAME="DeviceFont" VALUE="0"><PARAM NAME="EmbedMovie" VALUE="0"><PARAM NAME="BGColor" VALUE=""><PARAM NAME="SWRemote" VALUE=""><PARAM NAME="MovieData" VALUE=""><PARAM NAME="SeamlessTabbing" VALUE="1"><PARAM NAME="Profile" VALUE="0"><PARAM NAME="ProfileAddress" VALUE=""><PARAM NAME="ProfilePort" VALUE="0"><PARAM NAME="AllowNetworking" VALUE="all"><PARAM NAME="AllowFullScreen" VALUE="false"></OBJECT>

IE6:
Write调用前:
<object id="demo" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="300" height="100" style="undefined"><param name="movie" value="demo.swf" /><param name="bgcolor" value="#fff" /><param name="quality" value="high" /></object>

Write调用后:
<OBJECT id=demo height=100 width=300 classid=clsid:D27CDB6E-AE6D-11cf-96B8-444553540000><PARAM NAME="_cx" VALUE="7938"><PARAM NAME="_cy" VALUE="2646"><PARAM NAME="FlashVars" VALUE=""><PARAM NAME="Movie" VALUE="demo.swf"><PARAM NAME="Src" VALUE="demo.swf"><PARAM NAME="WMode" VALUE="Window"><PARAM NAME="Play" VALUE="0"><PARAM NAME="Loop" VALUE="-1"><PARAM NAME="Quality" VALUE="High"><PARAM NAME="SAlign" VALUE=""><PARAM NAME="Menu" VALUE="-1"><PARAM NAME="Base" VALUE=""><PARAM NAME="AllowScriptAccess" VALUE=""><PARAM NAME="Scale" VALUE="ShowAll"><PARAM NAME="DeviceFont" VALUE="0"><PARAM NAME="EmbedMovie" VALUE="0"><PARAM NAME="BGColor" VALUE=""><PARAM NAME="SWRemote" VALUE=""><PARAM NAME="MovieData" VALUE=""><PARAM NAME="SeamlessTabbing" VALUE="1"><PARAM NAME="Profile" VALUE="0"><PARAM NAME="ProfileAddress" VALUE=""><PARAM NAME="ProfilePort" VALUE="0"><PARAM NAME="AllowNetworking" VALUE="all"><PARAM NAME="AllowFullScreen" VALUE="false"></OBJECT>

  显然,IE浏览器对object便签做了很多处理,innerHTML强大功能的背后到底隐藏了什么?起初我怀疑是innerHTML有缓存机制,因此刷新的时候造成了bug,为了验证对着这个猜测,我给写入的flash字符串中添加了一个时间戳来“刷新缓存”,BUG依然存在,排除了这个缓存猜测。
如果换作其他的动态写入是否也有这个BUG呢?于是想到了document.write,在这个实例中,针对object和embed我做了单独输出,测试发现document.write写入前后的flash节点改变跟innerHTML前后的改变是一致的,但刷新BUG没有出现。难道这个BUG真的是innerHTML的内部实现造成的,如果真是这样那麻烦就大了,总不能指望微软现在来改IE6吧。

  六、只有google一下innerHTML的内部机制了
  首先google了一下innerHTML和externalInterface,想看看是否也有人遇到这个问题了。直接G到一篇SWFObject论坛上的一个讨论,对于Geoff在这里提到了几种造成externalInterface通信失败的可能性,我的实例中都没有出现,可是BUG依然存在。不过这则讨论中的一个细节引起了我注意,Geoff说他们在开发中一直都在使用externalInterface和js通信,从来没有出现过bug,我也仔细看了他给出的demo,这里是AS调Js的方法。难道innerHTM只对addCallBack有负作用,call是正常的?于是我又做了一个demo,这真是一个让我很无语的结论,原来call方法真的是有效的。也就是说innerHTML只对addCallBack有刷新bug。随后google到一个 flex写的externalInterface通信的例子更让我觉得无语。我把这个flex写的swf文件保存到了本地,并调用了其中addCallBack注册的方法,察看实例,“灵异事件”发生了,无论我怎么刷新页面,此前的bug都没有出现。一下让我将怀疑对象从innerHTML转移到了AS2中的externalInterface类本身。不过这里还有一个疑问就是为何只在IE6内核的多标签浏览器下才有此BUG呢?个人觉得可能性较大的原因是AS2中的externalInterface类确实还不完善,对于多标签浏览器中更复杂的window对象的兼容做得还不够好。而flex中采用的externalInterface机制可能更完善了。

  下班回来从7:30到11:30,整整四个小时的Debug最终结论居然出是因为AS2的内部实现有bug,在SWFUpload官方更改自己AS内部实现前,看来暂时只有先采用曲线救国的方式了:

  一、之前所提到的实例生成时,直接打印出SWFUpload中getFlashHTML方法针对object和embed的不同输出,然后将这两段代码分别针对不同浏览器做硬编码输出,切忌这两段代码不能共存。

  二、禁止掉SWFUpload中loadFlash,然后扩展一个方法,利用document.write在指定dom位置调用,动态写入flash元素。目前项目中我已经这样做了,比第一种方法的扩展性要高点。
娱乐休闲专区A 影视预告B 音乐咖啡C 英语阶梯D 生活百科
网页编程专区E AMPZF HTMLG CSSH JSI ASPJ PHPK JSPL MySQLM AJAX
Linux技术区 N 系统管理O 服务器架设P 网络/硬件Q 编程序开发R 内核/嵌入
管理中心专区S 发布网址T 版主议事U 事务处理