1 jQuery.extend({
2
3
4 createUploadIframe: function (id, uri) {//id为当前系统时间字符串,uri是外部传入的json对象的一个参数
5 //create frame
6 var frameId = 'jUploadFrame' + id; //给iframe添加一个独一无二的id
7 var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"'; //创建iframe元素
8 if (window.ActiveXObject) {//判断浏览器是否支持ActiveX控件
9 if (typeof uri == 'boolean') {
10 iframeHtml += ' src="' + 'javascript:false' + '"';
11
12 }
13 else if (typeof uri == 'string') {
14 iframeHtml += ' src="' + uri + '"';
15 }
16 }
17 iframeHtml += ' />';
18 jQuery(iframeHtml).appendTo(document.body); //将动态iframe追加到body中
19
20 return jQuery('#' + frameId).get(0); //返回iframe对象
21 },
22 createUploadForm: function (id, fileElementId, data) {//id为当前系统时间字符串,fileElementId为页面<input type='file' />的id,data的值需要根据传入json的键来决定
23 //create form
24 var formId = 'jUploadForm' + id; //给form添加一个独一无二的id
25 var fileId = 'jUploadFile' + id; //给<input type='file' />添加一个独一无二的id
26 var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data" ></form>'); //创建form元素
27 if (data) {//通常为false
28 for (var i in data) {
29 jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form); //根据data的内容,创建隐藏域,这部分我还不知道是什么时候用到。估计是传入json的时候,如果默认传一些参数的话要用到。
30 }
31 }
32 var oldElement = jQuery('#' + fileElementId); //得到页面中的<input type='file' />对象
33 var newElement = jQuery(oldElement).clone(); //克隆页面中的<input type='file' />对象
34 jQuery(oldElement).attr('id', fileId); //修改原对象的id
35 jQuery(oldElement).before(newElement); //在原对象前插入克隆对象
36 jQuery(oldElement).appendTo(form); //把原对象插入到动态form的结尾处
37
38
39
40 //set attributes
41 jQuery(form).css('position', 'absolute'); //给动态form添加样式,使其浮动起来,
42 jQuery(form).css('top', '-1200px');
43 jQuery(form).css('left', '-1200px');
44 jQuery(form).appendTo('body'); //把动态form插入到body中
45 return form;
46 },
47
48 ajaxFileUpload: function (s) {//这里s是个json对象,传入一些ajax的参数
49 // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
50 s = jQuery.extend({}, jQuery.ajaxSettings, s); //此时的s对象是由jQuery.ajaxSettings和原s对象扩展后的对象
51 var id = new Date().getTime(); //取当前系统时间,目的是得到一个独一无二的数字
52 var form = jQuery.createUploadForm(id, s.fileElementId, (typeof (s.data) == 'undefined' ? false : s.data)); //创建动态form
53 var io = jQuery.createUploadIframe(id, s.secureuri); //创建动态iframe
54 var frameId = 'jUploadFrame' + id; //动态iframe的id
55 var formId = 'jUploadForm' + id; //动态form的id
56 // Watch for a new set of requests
57 if (s.global && !jQuery.active++) {//当jQuery开始一个ajax请求时发生
58 jQuery.event.trigger("ajaxStart"); //触发ajaxStart方法
59 }
60 var requestDone = false; //请求完成标志
61 // Create the request object
62 var xml = {};
63 if (s.global)
64 jQuery.event.trigger("ajaxSend", [xml, s]); //触发ajaxSend方法
65 // Wait for a response to come back
66 var uploadCallback = function (isTimeout) {//回调函数
67 var io = document.getElementById(frameId); //得到iframe对象
68 try {
69 if (io.contentWindow) {//动态iframe所在窗口对象是否存在
70 xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
71 xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
72
73 } else if (io.contentDocument) {//动态iframe的文档对象是否存在
74 xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
75 xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
76 }
77 } catch (e) {
78 jQuery.handleError(s, xml, null, e);
79 }
80 if (xml || isTimeout == "timeout") {//xml变量被赋值或者isTimeout == "timeout"都表示请求发出,并且有响应
81 requestDone = true; //请求完成
82 var status;
83 try {
84 status = isTimeout != "timeout" ? "success" : "error"; //如果不是“超时”,表示请求成功
85 // Make sure that the request was successful or notmodified
86 if (status != "error") {
87 // process the data (runs the xml through httpData regardless of callback)
88 var data = jQuery.uploadHttpData(xml, s.dataType); //根据传送的type类型,返回json对象,此时返回的data就是后台操作后的返回结果
89 // If a local callback was specified, fire it and pass it the data
90 if (s.success)
91 s.success(data, status); //执行上传成功的操作
92
93 // Fire the global callback
94 if (s.global)
95 jQuery.event.trigger("ajaxSuccess", [xml, s]);
96 } else
97 jQuery.handleError(s, xml, status);
98 } catch (e) {
99 status = "error";
100 jQuery.handleError(s, xml, status, e);
101 }
102
103 // The request was completed
104 if (s.global)
105 jQuery.event.trigger("ajaxComplete", [xml, s]);
106
107 // Handle the global AJAX counter
108 if (s.global && ! --jQuery.active)
109 jQuery.event.trigger("ajaxStop");
110
111 // Process result
112 if (s.complete)
113 s.complete(xml, status);
114
115 jQuery(io).unbind();//移除iframe的事件处理程序
116
117 setTimeout(function () {//设置超时时间
118 try {
119 jQuery(io).remove();//移除动态iframe
120 jQuery(form).remove();//移除动态form
121
122 } catch (e) {
123 jQuery.handleError(s, xml, null, e);
124 }
125
126 }, 100)
127
128 xml = null
129
130 }
131 }
132 // Timeout checker
133 if (s.timeout > 0) {//超时检测
134 setTimeout(function () {
135 // Check to see if the request is still happening
136 if (!requestDone) uploadCallback("timeout");//如果请求仍未完成,就发送超时信号
137 }, s.timeout);
138 }
139 try {
140
141 var form = jQuery('#' + formId);
142 jQuery(form).attr('action', s.url);//传入的ajax页面导向url
143 jQuery(form).attr('method', 'POST');//设置提交表单方式
144 jQuery(form).attr('target', frameId);//返回的目标iframe,就是创建的动态iframe
145 if (form.encoding) {//选择编码方式
146 jQuery(form).attr('encoding', 'multipart/form-data');
147 }
148 else {
149 jQuery(form).attr('enctype', 'multipart/form-data');
150 }
151 jQuery(form).submit();//提交form表单
152
153 } catch (e) {
154 jQuery.handleError(s, xml, null, e);
155 }
156
157 jQuery('#' + frameId).load(uploadCallback); //ajax 请求从服务器加载数据,同时传入回调函数
158 return { abort: function () { } };
159
160 },
161
162 uploadHttpData: function (r, type) {
163 var data = !type;
164 data = type == "xml" || data ? r.responseXML : r.responseText;
165 // If the type is "script", eval it in global context
166 if (type == "script")
167 jQuery.globalEval(data);
168 // Get the JavaScript object, if JSON is used.
169 if (type == "json")
170 eval("data = " + data);
171 // evaluate scripts within html
172 if (type == "html")
173 jQuery("<div>").html(data).evalScripts();
174
175 return data;
176 },
177 handleError: function( s, xhr, status, e ) {
178 // If a local callback was specified, fire it
179 if ( s.error ) {
180 s.error.call( s.context || s, xhr, status, e );
181 }
182
183 // Fire the global callback
184 if ( s.global ) {
185 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
186 }
187 },
188 })