打印

[经验分享] fileupload原码分析

fileupload原码分析

一.页面渲染代码分析
查看rcdemos中的文件上传一示例的页面源码,可以看到如下的代码:
复制内容到剪贴板
JSP 代码:
  1. <script type=\"text/javascript\">
  2. file_upload_cb_func=function(){};
  3. if(typeof(changeCbFunc) == 'undefined'){
  4.   changeCbFunc = function(source, url, params, immediate){
  5.      return function(){
  6.         var form_var = OM.ajax.getParentForm(source);
  7.         form_var.enctype = form_var.oldEnctype;
  8.         form_var.target = form_var.oldTarget;
  9.         OM.ajax.ajaxSubmit(source, url, params, immediate);
  10.      };
  11.   }
  12. }
  13. var currentTime = new Date().getTime()
  14. if(typeof(OM.ajax.ajaxSubmit) == 'undefined'){
  15.   OM.ajax.ajaxSubmit = OM.ajax.submit;
  16. }
  17. if(typeof(OM.ajax.submit.overwrite) == 'undefined'){
  18.   OM.ajax.submit = function(source, url, params, immediate) {
  19.    var sourceForm = this.getParentForm(source);
  20.    if (sourceForm && sourceForm.has_file_upload) {
  21.     sourceForm.oldEnctype = sourceForm.enctype;
  22.     sourceForm.oldTarget = sourceForm.target;
  23.     sourceForm.enctype = 'multipart/form-data';
  24.     sourceForm.target = sourceForm.file_upload_iframe_name;
  25.     myForm$j_id7.start();
  26.     file_upload_cb_func = changeCbFunc(source, url, params, immediate);
  27.     sourceForm.nonAjaxSubmit();
  28.    }else{
  29.     OM.ajax.ajaxSubmit(source, url, params, immediate);
  30.    }
  31.   };
  32.   OM.ajax.submit.overwrite=true;
  33. }
  34. //-->
  35. </script>
  36. <iframe id='myForm_file_upload_iframe' name='myForm_file_upload_iframe' style='display:none' onload='file_upload_cb_func();'></iframe>
  37. <script type=\"text/javascript\">
  38. <!--
  39.   if(Ext&&Ext.onReady){
  40.   Ext.onReady(function(){
  41.    var parentForm = document.getElementById('myForm');
  42.    parentForm.has_file_upload=true;
  43.    parentForm.file_upload_iframe_name='myForm_file_upload_iframe';
  44.   });
  45.   }
  46. //-->
  47. </script>
分析上述的javascript:
1.页面生成的隐藏的iframe(display:none),该iframe主要用于上传文件,注意里面有一个onload='file_upload_cb_func();'回调方法,该方法进行Ajax的提交,真正执行用户的后台方法
2.设置changeCbFunc函数,在文件上传时赋值给iframe的onload里的file_upload_cb_func,回调时实际调用的changeCbFunc
3.设置OM.ajax.ajaxSubmit
4.覆写OM.ajax.submit方法,若为文件上传,则进行nonAjaxSubmit的提交,nonAjaxSubmit在ajax-debug.js中的initForm方法中定义可以看到,该方法进行了sourceForm.target的设置,使上传的时候sourceForm对应于隐藏的iframe,在iframe上进行非AJAX的文件上传,完成上传后即调用iframe的onload进行,回调fileupload对应的action操作
草图如下:


二.FileUpload组件的原码分析
分析AjaxFileUploadRenderer,重点是encodeEnd()方法
如果请求是非Ajax请求:
1.第一次进入页面:isAjaxHtmlResponse方法里,renderFileUploadField负责在第一次打开页面时渲染出javascript及fileUpload的html代码
2.文件上传时:processUploading(context, component)方法负责文件的上传
上传完成后将Mediator停止掉(Mediator主要是用于Progress的处理等)


三.ajax请求,进度条的更新
3.更新Mediator的状态

详情请查下面的流程图或者查看AjaxFileUploadRenderer的encodeEnd()源码:


四.总结
关于encodeEnd方法里执行的过程主要是参考apache的上传来看,OperaMasks中引用了apache的上传方式来进行文件的上传,网上可以查到很多关于apache 的上传文件源码的分析。

[ 本帖最后由 peter 于 2010-2-5 08:49 编辑 ]

TOP