一.页面渲染代码分析
查看rcdemos中的文件上传一示例的页面源码,可以看到如下的代码:
复制内容到剪贴板JSP 代码:
<script type=\"text/javascript\">
file_upload_cb_func=function(){};
if(typeof(changeCbFunc) == 'undefined'){
changeCbFunc = function(source, url, params, immediate){
return function(){
var form_var = OM.ajax.getParentForm(source);
form_var.enctype = form_var.oldEnctype;
form_var.target = form_var.oldTarget;
OM.ajax.ajaxSubmit(source, url, params, immediate);
};
}
}
var currentTime = new Date().getTime()
if(typeof(OM.ajax.ajaxSubmit) == 'undefined'){
OM.ajax.ajaxSubmit = OM.ajax.submit;
}
if(typeof(OM.ajax.submit.overwrite) == 'undefined'){
OM.ajax.submit = function(source, url, params, immediate) {
var sourceForm = this.getParentForm(source);
if (sourceForm && sourceForm.has_file_upload) {
sourceForm.oldEnctype = sourceForm.enctype;
sourceForm.oldTarget = sourceForm.target;
sourceForm.enctype = 'multipart/form-data';
sourceForm.target = sourceForm.file_upload_iframe_name;
myForm$j_id7.start();
file_upload_cb_func = changeCbFunc(source, url, params, immediate);
sourceForm.nonAjaxSubmit();
}else{
OM.ajax.ajaxSubmit(source, url, params, immediate);
}
};
OM.ajax.submit.overwrite=true;
}
//-->
</script>
<iframe id='myForm_file_upload_iframe' name='myForm_file_upload_iframe' style='display:none' onload='file_upload_cb_func();'></iframe>
<script type=\"text/javascript\">
<!--
if(Ext&&Ext.onReady){
Ext.onReady(function(){
var parentForm = document.getElementById('myForm');
parentForm.has_file_upload=true;
parentForm.file_upload_iframe_name='myForm_file_upload_iframe';
});
}
//-->
</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 编辑 ]