AjaxUpLoad.js的使用实现无刷新文件上传,如图。

图1 文件上传前

图2 文件上传后

1、创建页面并编写HTML

[html] view plaincopy

 
  1. 上传文档:
  2. <div class="uploadFile">
  3. <span id="doc"><input type="text" disabled="disabled" /></span>
  4. <input type="hidden" id="hidFileName"  />
  5. <input type="button" id="btnUploadFile" value="上传" />
  6. <input type="button" id="btnDeleteFile" value="删除"  />
  7. </div>
  8. 上传图片:
  9. <div class="uploadImg">
  10. <img id="imgShow" src="/images/nophoto.gif" />
  11. <input type="hidden" id="hidImgName" />
  12. <input type="button" id="btnUploadImg" value="上传" />
  13. <input type="button" id="btnDeleteImg" value="删除" />
  14. </div>

2、引用AjaxUpload.js文件

[html] view plaincopy

 
  1. <script src="/js/common/AjaxUpload.js" type="text/javascript"></script>

3、编写JS脚本

[java] view plaincopy

 
  1. window.onload = function() {
  2. init();  //初始化
  3. }
  4. //初始化
  5. function init() {
  6. //初始化文档上传
  7. var btnFile = document.getElementById("btnUploadFile");
  8. var doc = document.getElementById("doc");
  9. var hidFileName = document.getElementById("hidFileName");
  10. document.getElementById("btnDeleteFile").onclick = function() { DelFile(doc, hidFileName); };
  11. g_AjxUploadFile(btnFile, doc, hidFileName);
  12. //初始化图片上传
  13. var btnImg = document.getElementById("btnUploadImg");
  14. var img = document.getElementById("imgShow");
  15. var hidImgName = document.getElementById("hidImgName");
  16. document.getElementById("btnDeleteImg").onclick = function() { DelImg(img, hidImgName); };
  17. g_AjxUploadImg(btnImg, img, hidImgName);
  18. }
  19. var g_AjxTempDir = "/file/temp/";
  20. //文档上传
  21. function g_AjxUploadFile(btn, doc, hidPut, action) {
  22. var button = btn, interval;
  23. new AjaxUpload(button, {
  24. action: ((action == null || action == undefined) ? '/Common/UploadHandler.ashx?fileType=file' : action),
  25. data: {},
  26. name: 'myfile',
  27. onSubmit: function(file, ext) {
  28. if (!(ext && /^(rar|zip|pdf|pdfx|txt|csv|xls|xlsx|doc|docx|RAR|ZIP|PDF|PDFX|TXT|CSV|XLS|XLSX|DOC|DOCX)$/.test(ext))) {
  29. alert("您上传的文档格式不对,请重新选择!");
  30. return false;
  31. }
  32. },
  33. onComplete: function(file, response) {
  34. flagValue = response;
  35. if (flagValue == "1") {
  36. alert("您上传的文档格式不对,请重新选择!");
  37. }
  38. else if (flagValue == "2") {
  39. alert("您上传的文档大于2M,请重新选择!");
  40. }
  41. else if (flagValue == "3") {
  42. alert("文档上传失败!");
  43. }
  44. else {
  45. hidPut.value = response;
  46. doc.innerHTML="<a href='" + g_AjxTempDir + response + "' target='_blank'>" + response + "</a>";
  47. }
  48. }
  49. });
  50. }
  51. //图片上传
  52. function g_AjxUploadImg(btn, img, hidPut) {
  53. var button = btn, interval;
  54. new AjaxUpload(button, {
  55. action: '/Common/UploadHandler.ashx?fileType=img',
  56. data: {},
  57. name: 'myfile',
  58. onSubmit: function(file, ext) {
  59. if (!(ext && /^(jpg|JPG|png|PNG|gif|GIF)$/.test(ext))) {
  60. alert("您上传的图片格式不对,请重新选择!");
  61. return false;
  62. }
  63. },
  64. onComplete: function(file, response) {
  65. flagValue = response;
  66. if (flagValue == "1") {
  67. alert("您上传的图片格式不对,请重新选择!");
  68. }
  69. else if (flagValue == "2") {
  70. alert("您上传的图片大于200K,请重新选择!");
  71. }
  72. else if (flagValue == "3") {
  73. alert("图片上传失败!");
  74. }
  75. else {
  76. hidPut.value = response;
  77. img.src = g_AjxTempDir + response;
  78. }
  79. }
  80. });
  81. }
  82. //删除文档
  83. function DelFile(doc, hidPut) {
  84. hidPut.value = "";
  85. doc.innerHTML = "<input type=\"text\" disabled=\"disabled\" />";
  86. }
  87. //删除图片
  88. function DelImg(img, hidPut) {
  89. hidPut.value = "";
  90. img.src = "/images/nophoto.gif";
  91. }

4、创建/Common/UploadHandler.ashx处理程序

[csharp] view plaincopy

 
  1. <%@ WebHandler Language="C#" Class="UploadHandler" %>
  2. using System;
  3. using System.Web;
  4. using System.Text.RegularExpressions;
  5. using System.IO;
  6. public class UploadHandler : IHttpHandler {
  7. private string _filedir = "";    //文件目录
  8. /// <summary>
  9. /// 处理上传文件(1:文件格式不正确、2:文件大小不正确、3:上传失败、文件名称:上传成功)
  10. /// </summary>
  11. /// <param name="context"></param>
  12. public void ProcessRequest (HttpContext context) {
  13. _filedir = context.Server.MapPath(@"/file/temp/");
  14. try
  15. {
  16. string result = "3";
  17. string fileType = context.Request.QueryString["fileType"]; //获取上传文件类型
  18. if (fileType == "file")
  19. {
  20. result = UploadFile(context);  //文档上传
  21. }
  22. else if (fileType == "img")
  23. {
  24. result = UploadImg(context);   //图片上传
  25. }
  26. context.Response.Write(result);
  27. }
  28. catch
  29. {
  30. context.Response.Write("3");//3文件上传失败
  31. }
  32. }
  33. /// <summary>
  34. /// 文档上传
  35. /// </summary>
  36. /// <param name="context"></param>
  37. /// <returns></returns>
  38. private string UploadFile(HttpContext context)
  39. {
  40. int cout = context.Request.Files.Count;
  41. if (cout > 0)
  42. {
  43. HttpPostedFile hpf = context.Request.Files[0];
  44. if (hpf != null)
  45. {
  46. string fileExt = Path.GetExtension(hpf.FileName).ToLower();
  47. //只能上传文件,过滤不可上传的文件类型
  48. string fileFilt = ".rar|.zip|.pdf|.pdfx|.txt|.csv|.xls|.xlsx|.doc|.docx......";
  49. if (fileFilt.IndexOf(fileExt) <= -1)
  50. {
  51. return "1";
  52. }
  53. //判断文件大小
  54. int length = hpf.ContentLength;
  55. if (length > 2097152)
  56. {
  57. return "2";
  58. }
  59. Random rd = new Random();
  60. DateTime nowTime = DateTime.Now;
  61. string newFileName = nowTime.Year.ToString() + nowTime.Month.ToString() + nowTime.Day.ToString() + nowTime.Hour.ToString() + nowTime.Minute.ToString() + nowTime.Second.ToString() + rd.Next(1000, 1000000) + Path.GetExtension(hpf.FileName);
  62. if (!Directory.Exists(_filedir))
  63. {
  64. Directory.CreateDirectory(_filedir);
  65. }
  66. string fileName = _filedir + newFileName;
  67. hpf.SaveAs(fileName);
  68. return newFileName;
  69. }
  70. }
  71. return "3";
  72. }
  73. /// <summary>
  74. /// 图片上传
  75. /// </summary>
  76. /// <param name="context"></param>
  77. /// <returns></returns>
  78. private string UploadImg(HttpContext context)
  79. {
  80. int cout = context.Request.Files.Count;
  81. if (cout > 0)
  82. {
  83. HttpPostedFile hpf = context.Request.Files[0];
  84. if (hpf != null)
  85. {
  86. string fileExt = Path.GetExtension(hpf.FileName).ToLower();
  87. //只能上传文件,过滤不可上传的文件类型
  88. string fileFilt = ".gif|.jpg|.php|.jsp|.jpeg|.png|......";
  89. if (fileFilt.IndexOf(fileExt) <= -1)
  90. {
  91. return "1";
  92. }
  93. //判断文件大小
  94. int length = hpf.ContentLength;
  95. if (length > 204800)
  96. {
  97. return "2";
  98. }
  99. Random rd = new Random();
  100. DateTime nowTime = DateTime.Now;
  101. string newFileName = nowTime.Year.ToString() + nowTime.Month.ToString() + nowTime.Day.ToString() + nowTime.Hour.ToString() + nowTime.Minute.ToString() + nowTime.Second.ToString() + rd.Next(1000, 1000000) + Path.GetExtension(hpf.FileName);
  102. if (!Directory.Exists(_filedir))
  103. {
  104. Directory.CreateDirectory(_filedir);
  105. }
  106. string fileName = _filedir + newFileName;
  107. hpf.SaveAs(fileName);
  108. return newFileName;
  109. }
  110. }
  111. return "3";
  112. }
  113. #region IHttpHandler 成员
  114. public bool IsReusable
  115. {
  116. get { throw new NotImplementedException(); }
  117. }
  118. #endregion
  119. }

附件1:页面CSS样式

[css] view plaincopy

 
  1. /*上传文件*/
  2. .uploadFile{margin-bottom:10px;}
  3. /*上传图片*/
  4. .uploadImg{}
  5. .uploadImg img{width:102px; height:64px; border:1px solid #CCCCCC; display: block;}

附件2:AjaxUpload.js文件

[javascript] view plaincopy

 
  1. /**
  2. * AJAX Upload ( http://valums.com/ajax-upload/ )
  3. * Copyright (c) Andris Valums
  4. * Licensed under the MIT license ( http://valums.com/mit-license/ )
  5. * Thanks to Gary Haran, David Mark, Corey Burns and others for contributions
  6. */
  7. (function () {
  8. /* global window */
  9. /* jslint browser: true, devel: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true */
  10. /**
  11. * Wrapper for FireBug's console.log
  12. */
  13. function log() {
  14. if (typeof(console) != 'undefined' && typeof(console.log) == 'function') {
  15. Array.prototype.unshift.call(arguments, '[Ajax Upload]');
  16. console.log(Array.prototype.join.call(arguments, ' '));
  17. }
  18. }
  19. /**
  20. * Attaches event to a dom element.
  21. * @param {Element} el
  22. * @param type event name
  23. * @param fn callback This refers to the passed element
  24. */
  25. function addEvent(el, type, fn) {
  26. if (el.addEventListener) {
  27. el.addEventListener(type, fn, false);
  28. } else if (el.attachEvent) {
  29. el.attachEvent('on' + type, function () {
  30. fn.call(el);
  31. });
  32. } else {
  33. throw new Error('not supported or DOM not loaded');
  34. }
  35. }
  36. /**
  37. * Attaches resize event to a window, limiting
  38. * number of event fired. Fires only when encounteres
  39. * delay of 100 after series of events.
  40. *
  41. * Some browsers fire event multiple times when resizing
  42. * http://www.quirksmode.org/dom/events/resize.html
  43. *
  44. * @param fn callback This refers to the passed element
  45. */
  46. function addResizeEvent(fn) {
  47. var timeout;
  48. addEvent(window, 'resize', function () {
  49. if (timeout) {
  50. clearTimeout(timeout);
  51. }
  52. timeout = setTimeout(fn, 100);
  53. });
  54. }
  55. // Needs more testing, will be rewriten for next version
  56. // getOffset function copied from jQuery lib (http://jquery.com/)
  57. if (document.documentElement.getBoundingClientRect) {
  58. // Get Offset using getBoundingClientRect
  59. // http://ejohn.org/blog/getboundingclientrect-is-awesome/
  60. var getOffset = function (el) {
  61. var box = el.getBoundingClientRect();
  62. var doc = el.ownerDocument;
  63. var body = doc.body;
  64. var docElem = doc.documentElement; // for ie
  65. var clientTop = docElem.clientTop || body.clientTop || 0;
  66. var clientLeft = docElem.clientLeft || body.clientLeft || 0;
  67. // In Internet Explorer 7 getBoundingClientRect property is treated as physical,
  68. // while others are logical. Make all logical, like in IE8.
  69. var zoom = 1;
  70. if (body.getBoundingClientRect) {
  71. var bound = body.getBoundingClientRect();
  72. zoom = (bound.right - bound.left) / body.clientWidth;
  73. }
  74. if (zoom > 1) {
  75. clientTop = 0;
  76. clientLeft = 0;
  77. }
  78. var top = box.top / zoom + (window.pageYOffset || docElem && docElem.scrollTop / zoom || body.scrollTop / zoom) - clientTop,
  79. left = box.left / zoom + (window.pageXOffset || docElem && docElem.scrollLeft / zoom || body.scrollLeft / zoom) - clientLeft;
  80. return {
  81. top: top,
  82. left: left
  83. };
  84. };
  85. } else {
  86. // Get offset adding all offsets
  87. var getOffset = function (el) {
  88. var top = 0,
  89. left = 0;
  90. do {
  91. top += el.offsetTop || 0;
  92. left += el.offsetLeft || 0;
  93. el = el.offsetParent;
  94. } while (el);
  95. return {
  96. left: left,
  97. top: top
  98. };
  99. };
  100. }
  101. /**
  102. * Returns left, top, right and bottom properties describing the border-box,
  103. * in pixels, with the top-left relative to the body
  104. * @param {Element} el
  105. * @return {Object} Contains left, top, right,bottom
  106. */
  107. function getBox(el) {
  108. var left, right, top, bottom;
  109. var offset = getOffset(el);
  110. left = offset.left;
  111. top = offset.top;
  112. right = left + el.offsetWidth;
  113. bottom = top + el.offsetHeight;
  114. return {
  115. left: left,
  116. right: right,
  117. top: top,
  118. bottom: bottom
  119. };
  120. }
  121. /**
  122. * Helper that takes object literal
  123. * and add all properties to element.style
  124. * @param {Element} el
  125. * @param {Object} styles
  126. */
  127. function addStyles(el, styles) {
  128. for (var name in styles) {
  129. if (styles.hasOwnProperty(name)) {
  130. el.style[name] = styles[name];
  131. }
  132. }
  133. }
  134. /**
  135. * Function places an absolutely positioned
  136. * element on top of the specified element
  137. * copying position and dimentions.
  138. * @param {Element} from
  139. * @param {Element} to
  140. */
  141. function copyLayout(from, to) {
  142. var box = getBox(from);
  143. addStyles(to, {
  144. position: 'absolute',
  145. left: box.left + 'px',
  146. top: box.top + 'px',
  147. width: from.offsetWidth + 'px',
  148. height: from.offsetHeight + 'px'
  149. });
  150. }
  151. /**
  152. * Creates and returns element from html chunk
  153. * Uses innerHTML to create an element
  154. */
  155. var toElement = (function () {
  156. var div = document.createElement('div');
  157. return function (html) {
  158. div.innerHTML = html;
  159. var el = div.firstChild;
  160. return div.removeChild(el);
  161. };
  162. })();
  163. /**
  164. * Function generates unique id
  165. * @return unique id
  166. */
  167. var getUID = (function () {
  168. var id = 0;
  169. return function () {
  170. return 'ValumsAjaxUpload' + id++;
  171. };
  172. })();
  173. /**
  174. * Get file name from path
  175. * @param {String} file path to file
  176. * @return filename
  177. */
  178. function fileFromPath(file) {
  179. return file.replace(/.*(\/|\\)/, "");
  180. }
  181. /**
  182. * Get file extension lowercase
  183. * @param {String} file name
  184. * @return file extenstion
  185. */
  186. function getExt(file) {
  187. return (-1 !== file.indexOf('.')) ? file.replace(/.*[.]/, '') : '';
  188. }
  189. function hasClass(el, name) {
  190. var re = new RegExp('\\b' + name + '\\b');
  191. return re.test(el.className);
  192. }
  193. function addClass(el, name) {
  194. if (!hasClass(el, name)) {
  195. el.className += ' ' + name;
  196. }
  197. }
  198. function removeClass(el, name) {
  199. var re = new RegExp('\\b' + name + '\\b');
  200. el.className = el.className.replace(re, '');
  201. }
  202. function removeNode(el) {
  203. el.parentNode.removeChild(el);
  204. }
  205. /**
  206. * Easy styling and uploading
  207. * @constructor
  208. * @param button An element you want convert to
  209. * upload button. Tested dimentions up to 500x500px
  210. * @param {Object} options See defaults below.
  211. */
  212. window.AjaxUpload = function (button, options) {
  213. this._settings = {
  214. // Location of the server-side upload script
  215. action: 'upload.php',
  216. // File upload name
  217. name: 'userfile',
  218. // Additional data to send
  219. data: {},
  220. // Submit file as soon as it's selected
  221. autoSubmit: true,
  222. // The type of data that you're expecting back from the server.
  223. // html and xml are detected automatically.
  224. // Only useful when you are using json data as a response.
  225. // Set to "json" in that case.
  226. responseType: false,
  227. // Class applied to button when mouse is hovered
  228. hoverClass: 'hover',
  229. // Class applied to button when AU is disabled
  230. disabledClass: 'disabled',
  231. // When user selects a file, useful with autoSubmit disabled
  232. // You can return false to cancel upload
  233. onChange: function (file, extension) {},
  234. // Callback to fire before file is uploaded
  235. // You can return false to cancel upload
  236. onSubmit: function (file, extension) {},
  237. // Fired when file upload is completed
  238. // WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
  239. onComplete: function (file, response) {}
  240. };
  241. // Merge the users options with our defaults
  242. for (var i in options) {
  243. if (options.hasOwnProperty(i)) {
  244. this._settings[i] = options[i];
  245. }
  246. }
  247. // button isn't necessary a dom element
  248. if (button.jquery) {
  249. // jQuery object was passed
  250. button = button[0];
  251. } else if (typeof button == "string") {
  252. if (/^#.*/.test(button)) {
  253. // If jQuery user passes #elementId don't break it
  254. button = button.slice(1);
  255. }
  256. button = document.getElementById(button);
  257. }
  258. if (!button || button.nodeType !== 1) {
  259. throw new Error("Please make sure that you're passing a valid element");
  260. }
  261. if (button.nodeName.toUpperCase() == 'A') {
  262. // disable link
  263. addEvent(button, 'click', function (e) {
  264. if (e && e.preventDefault) {
  265. e.preventDefault();
  266. } else if (window.event) {
  267. window.event.returnValue = false;
  268. }
  269. });
  270. }
  271. // DOM element
  272. this._button = button;
  273. // DOM element
  274. this._input = null;
  275. // If disabled clicking on button won't do anything
  276. this._disabled = false;
  277. // if the button was disabled before refresh if will remain
  278. // disabled in FireFox, let's fix it
  279. this.enable();
  280. this._rerouteClicks();
  281. };
  282. // assigning methods to our class
  283. AjaxUpload.prototype = {
  284. setData: function (data) {
  285. this._settings.data = data;
  286. },
  287. disable: function () {
  288. addClass(this._button, this._settings.disabledClass);
  289. this._disabled = true;
  290. var nodeName = this._button.nodeName.toUpperCase();
  291. if (nodeName == 'INPUT' || nodeName == 'BUTTON') {
  292. this._button.setAttribute('disabled', 'disabled');
  293. }
  294. // hide input
  295. if (this._input) {
  296. // We use visibility instead of display to fix problem with Safari 4
  297. // The problem is that the value of input doesn't change if it
  298. // has display none when user selects a file
  299. this._input.parentNode.style.visibility = 'hidden';
  300. }
  301. },
  302. enable: function () {
  303. removeClass(this._button, this._settings.disabledClass);
  304. this._button.removeAttribute('disabled');
  305. this._disabled = false;
  306. },
  307. /**
  308. * Creates invisible file input
  309. * that will hover above the button
  310. * <div><input type='file' /></div>
  311. */
  312. _createInput: function () {
  313. var self = this;
  314. var input = document.createElement("input");
  315. input.setAttribute('type', 'file');
  316. input.setAttribute('name', this._settings.name);
  317. addStyles(input, {
  318. 'position': 'absolute',
  319. // in Opera only 'browse' button
  320. // is clickable and it is located at
  321. // the right side of the input
  322. 'right': 0,
  323. 'margin': 0,
  324. 'padding': 0,
  325. 'fontSize': '480px',
  326. 'cursor': 'pointer'
  327. });
  328. var div = document.createElement("div");
  329. addStyles(div, {
  330. 'display': 'block',
  331. 'position': 'absolute',
  332. 'overflow': 'hidden',
  333. 'margin': 0,
  334. 'padding': 0,
  335. 'opacity': 0,
  336. // Make sure browse button is in the right side
  337. // in Internet Explorer
  338. 'direction': 'ltr',
  339. //Max zIndex supported by Opera 9.0-9.2
  340. 'zIndex': 2147483583
  341. });
  342. // Make sure that element opacity exists.
  343. // Otherwise use IE filter
  344. if (div.style.opacity !== "0") {
  345. if (typeof(div.filters) == 'undefined') {
  346. throw new Error('Opacity not supported by the browser');
  347. }
  348. div.style.filter = "alpha(opacity=0)";
  349. }
  350. addEvent(input, 'change', function () {
  351. if (!input || input.value === '') {
  352. return;
  353. }
  354. // Get filename from input, required
  355. // as some browsers have path instead of it
  356. var file = fileFromPath(input.value);
  357. if (false === self._settings.onChange.call(self, file, getExt(file))) {
  358. self._clearInput();
  359. return;
  360. }
  361. // Submit form when value is changed
  362. if (self._settings.autoSubmit) {
  363. self.submit();
  364. }
  365. });
  366. addEvent(input, 'mouseover', function () {
  367. addClass(self._button, self._settings.hoverClass);
  368. });
  369. addEvent(input, 'mouseout', function () {
  370. removeClass(self._button, self._settings.hoverClass);
  371. // We use visibility instead of display to fix problem with Safari 4
  372. // The problem is that the value of input doesn't change if it
  373. // has display none when user selects a file
  374. input.parentNode.style.visibility = 'hidden';
  375. });
  376. div.appendChild(input);
  377. document.body.appendChild(div);
  378. this._input = input;
  379. },
  380. _clearInput: function () {
  381. if (!this._input) {
  382. return;
  383. }
  384. // this._input.value = ''; Doesn't work in IE6
  385. removeNode(this._input.parentNode);
  386. this._input = null;
  387. this._createInput();
  388. removeClass(this._button, this._settings.hoverClass);
  389. },
  390. /**
  391. * Function makes sure that when user clicks upload button,
  392. * the this._input is clicked instead
  393. */
  394. _rerouteClicks: function () {
  395. var self = this;
  396. // IE will later display 'access denied' error
  397. // if you use using self._input.click()
  398. // other browsers just ignore click()
  399. addEvent(self._button, 'mouseover', function () {
  400. if (self._disabled) {
  401. return;
  402. }
  403. if (!self._input) {
  404. self._createInput();
  405. }
  406. var div = self._input.parentNode;
  407. copyLayout(self._button, div);
  408. div.style.visibility = 'visible';
  409. });
  410. // commented because we now hide input on mouseleave
  411. /**
  412. * When the window is resized the elements
  413. * can be misaligned if button position depends
  414. * on window size
  415. */
  416. //addResizeEvent(function(){
  417. //    if (self._input){
  418. //        copyLayout(self._button, self._input.parentNode);
  419. //    }
  420. //});
  421. },
  422. /**
  423. * Creates iframe with unique name
  424. * @return {Element} iframe
  425. */
  426. _createIframe: function () {
  427. // We can't use getTime, because it sometimes return
  428. // same value in safari :(
  429. var id = getUID();
  430. // We can't use following code as the name attribute
  431. // won't be properly registered in IE6, and new window
  432. // on form submit will open
  433. // var iframe = document.createElement('iframe');
  434. // iframe.setAttribute('name', id);
  435. var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
  436. // src="javascript:false; was added
  437. // because it possibly removes ie6 prompt
  438. // "This page contains both secure and nonsecure items"
  439. // Anyway, it doesn't do any harm.
  440. iframe.setAttribute('id', id);
  441. iframe.style.display = 'none';
  442. document.body.appendChild(iframe);
  443. return iframe;
  444. },
  445. /**
  446. * Creates form, that will be submitted to iframe
  447. * @param {Element} iframe Where to submit
  448. * @return {Element} form
  449. */
  450. _createForm: function (iframe) {
  451. var settings = this._settings;
  452. // We can't use the following code in IE6
  453. // var form = document.createElement('form');
  454. // form.setAttribute('method', 'post');
  455. // form.setAttribute('enctype', 'multipart/form-data');
  456. // Because in this case file won't be attached to request
  457. var form = toElement('<form method="post" enctype="multipart/form-data"></form>');
  458. form.setAttribute('action', settings.action);
  459. form.setAttribute('target', iframe.name);
  460. form.style.display = 'none';
  461. document.body.appendChild(form);
  462. // Create hidden input element for each data key
  463. for (var prop in settings.data) {
  464. if (settings.data.hasOwnProperty(prop)) {
  465. var el = document.createElement("input");
  466. el.setAttribute('type', 'hidden');
  467. el.setAttribute('name', prop);
  468. el.setAttribute('value', settings.data[prop]);
  469. form.appendChild(el);
  470. }
  471. }
  472. return form;
  473. },
  474. /**
  475. * Gets response from iframe and fires onComplete event when ready
  476. * @param iframe
  477. * @param file Filename to use in onComplete callback
  478. */
  479. _getResponse: function (iframe, file) {
  480. // getting response
  481. var toDeleteFlag = false,
  482. self = this,
  483. settings = this._settings;
  484. addEvent(iframe, 'load', function () {
  485. if ( // For Safari
  486. iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
  487. // For FF, IE
  488. iframe.src == "javascript:'<html></html>';") {
  489. // First time around, do not delete.
  490. // We reload to blank page, so that reloading main page
  491. // does not re-submit the post.
  492. if (toDeleteFlag) {
  493. // Fix busy state in FF3
  494. setTimeout(function () {
  495. removeNode(iframe);
  496. },
  497. 0);
  498. }
  499. return;
  500. }
  501. var doc = iframe.contentDocument ? iframe.contentDocument : window.frames[iframe.id].document;
  502. // fixing Opera 9.26,10.00
  503. if (doc.readyState && doc.readyState != 'complete') {
  504. // Opera fires load event multiple times
  505. // Even when the DOM is not ready yet
  506. // this fix should not affect other browsers
  507. return;
  508. }
  509. // fixing Opera 9.64
  510. if (doc.body && doc.body.innerHTML == "false") {
  511. // In Opera 9.64 event was fired second time
  512. // when body.innerHTML changed from false
  513. // to server response approx. after 1 sec
  514. return;
  515. }
  516. var response;
  517. if (doc.XMLDocument) {
  518. // response is a xml document Internet Explorer property
  519. response = doc.XMLDocument;
  520. } else if (doc.body) {
  521. // response is html document or plain text
  522. response = doc.body.innerHTML;
  523. if (settings.responseType && settings.responseType.toLowerCase() == 'json') {
  524. // If the document was sent as 'application/javascript' or
  525. // 'text/javascript', then the browser wraps the text in a <pre>
  526. // tag and performs html encoding on the contents.  In this case,
  527. // we need to pull the original text content from the text node's
  528. // nodeValue property to retrieve the unmangled content.
  529. // Note that IE6 only understands text/html
  530. if (doc.body.firstChild && doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {
  531. response = doc.body.firstChild.firstChild.nodeValue;
  532. }
  533. if (response) {
  534. response = eval("(" + response + ")");
  535. } else {
  536. response = {};
  537. }
  538. }
  539. } else {
  540. // response is a xml document
  541. response = doc;
  542. }
  543. settings.onComplete.call(self, file, response);
  544. // Reload blank page, so that reloading main page
  545. // does not re-submit the post. Also, remember to
  546. // delete the frame
  547. toDeleteFlag = true;
  548. // Fix IE mixed content issue
  549. iframe.src = "javascript:'<html></html>';";
  550. });
  551. },
  552. /**
  553. * Upload file contained in this._input
  554. */
  555. submit: function () {
  556. var self = this,
  557. settings = this._settings;
  558. if (!this._input || this._input.value === '') {
  559. return;
  560. }
  561. var file = fileFromPath(this._input.value);
  562. // user returned false to cancel upload
  563. if (false === settings.onSubmit.call(this, file, getExt(file))) {
  564. this._clearInput();
  565. return;
  566. }
  567. // sending request
  568. var iframe = this._createIframe();
  569. var form = this._createForm(iframe);
  570. // assuming following structure
  571. // div -> input type='file'
  572. removeNode(this._input.parentNode);
  573. removeClass(self._button, self._settings.hoverClass);
  574. form.appendChild(this._input);
  575. form.submit();
  576. // request set, clean up
  577. removeNode(form);
  578. form = null;
  579. removeNode(this._input);
  580. this._input = null;
  581. // Get response from iframe and fire onComplete event when ready
  582. this._getResponse(iframe, file);
  583. // get ready for next request
  584. this._createInput();
  585. }
  586. };
  587. })();

最新文章

  1. VS使用过程中,编写JS没有智能提示解决方法
  2. Ubuntu下解决adb devices:???????????? no permissions的方法
  3. FFmpeg-20160415-snapshot-bin
  4. Gossip protocol(zz)
  5. paip. 内存占用少的php ide选择评测总结
  6. 【NOIP 2016】斗地主
  7. node io.sockt 聊天应用
  8. 敏捷开发概述与路线(转自MBAlib)
  9. MapReduce中的Join算法
  10. Xcode6中如何修改文件中自动创建的Created by和Copyright
  11. Python学习之路——socket
  12. 增加 Java 有几个好习惯表现
  13. CRT
  14. JavaScript变量声明与提升
  15. 【zabbix教程系列】七、自动注册(Windows)
  16. 【转】避免全表扫描的sql优化
  17. Web App Manifest
  18. day73
  19. win8 应用商店程序使用SQLITE数据库
  20. postman接口测试——笔记

热门文章

  1. BootLoader作用
  2. java 接口(基础思想一)
  3. linux设备驱动模型
  4. PIGCMS提示“你的程序为盗版,非法授权,请联系QQ7530782或者8441010”的修复方法
  5. ServiceStack.OrmLite 调用存储过程
  6. Jquery 判断浏览器类型
  7. 【转】欧拉回路&amp;特殊图下的哈密顿回路题集
  8. Leetcode#79 Word Search
  9. phonegap 环境搭建
  10. 精通ASP.Net MVC 3 框架(第三版)学习笔记