最近做畢設的時候需要用到上傳圖片的功能,但是我的畢設全部的傳輸都是基於ajax的請求,百度了一圈發現TMD居然說ajax不能上傳文件!!當時我就不樂意了啊,那難道其他人都用的是黑科技嗎?!又來網上的大牛告訴說用jquery的一個插件就可以完成,百度了一下原來叫--ajaxfileupload.js
這又是個什么鬼!(╯‵□′)╯︵┴─┴為毛要用插件,來來來~ajax咋倆聊聊,你為毛不能上傳文件來着?
對於ajax是如何實現的我想大家都很清楚了,首先得到XmlHttpRequest對象實例的一個引用,可以創建一個新的XmlHttpRequest的實例。然后告訴XmlHttpRequest對象,那個函數回處理XmlHttpRequest對象的狀態的改變.為此要把對象的 onreadystatechange屬性設置為指向JavaScript的指針.接着指定請求屬性.XmlHttpRequest對象的Open()方法會指定將發送的請求.最后將請求發送給服務器.XmlHttpRequest對象的send()方法將請求發送到目標資源。下面是我在某前輩的博客里找到的圖片,這樣更直觀一些,謝謝~
屬性ajax的人肯定對XmlHttpRequest 對象不陌生吧,度娘告訴我說ajax的核心就是這個對象,那么我們就來看看XmlHttpRequest對象是如何上傳數據的吧~
// 首先我們先創建一個對象咯 var xmlHttp; function createXMLHttpRequest(){ if(window.ActiveXObject){ xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } else if(window.XMLHttpRequest){ xmlHttp = new XMLHttpRequest(); } } // 接着我們定義發送請求的方法 function AddNumber(){ createXMLHttpRequest(); var url= "AddHandler.ashx?num1="+document.getElementById("num1").value+ "&num2="+document.getElementById("num2").value; xmlHttp.open("GET",url,true); xmlHttp.onreadystatechange=ShowResult; xmlHttp.send(null); }
當然,ajax還有很多可說的,但是今天在這里單純的是討論一下在ajax中數據到底是如何發送到后台的呢?看過很多前輩的博客和文檔上都說其實ajax發送的是字符類型的對象,那這樣就很好理解為什么無法上傳文件這樣二進制的東西了~比較不能把二進制轉成字符串發吧…..(說不定真能額…..)但是又看到又說現在的HTML5可以原生的上傳文件了,不過目前不是所有瀏覽器都支持的呀~那還不能算是徹徹底底的解決方案咯~
既然不能上傳二進制文件,那之前的神器--ajaxfileupload.js又是如何完成這個看似“不可能”的任務的呢?
打開ajaxfileupload.js就會很明白的看懂里面說的啦~這樣引用一位前輩的博客http://blog.csdn.net/it_man/article/details/43800957這里面有對這個js很詳細的說明了,說白了~原來這個神器也不是通過ajax的方式上傳的呀~其實,這個插件的原理就是動態的生成一個隱藏的iframe來提交的數據,在數據提交完成后再悄悄的刪除掉,可是在我實際的使用中發現這個插件一次只能上傳一個文件額,對於有多文件上傳需求的我來說很不和諧額(╯‵□′)╯︵┴─┴
那我們就來改造改造這個插件吧~為什么一次只能上傳一個呢?是因為在插件中作者一次只取了一個元素的ID,那么我們就讓它一次多取幾個ID吧~
//var oldElement = jQuery('#' + fileElementId); //var newElement = jQuery(oldElement).clone(); //jQuery(oldElement).attr('id', fileId); //jQuery(oldElement).before(newElement); //jQuery(oldElement).appendTo(form); if(typeof(fileElementId) == 'string'){ fileElementId = [fileElementId]; } for(var i in fileElementId){ var oldElement = jQuery('#' + fileElementId[i]); var newElement = jQuery(oldElement).clone(); jQuery(oldElement).attr('id', fileId); jQuery(oldElement).before(newElement); jQuery(oldElement).appendTo(form); }
下面被我注釋掉的地方就是作者原來寫的,而我在下面從新改的是首先判斷傳人的值是否是一個字符串,如果是字符串那么就繼續按照以前的方式來處理,而當上傳多個文件的時候就通過循環來一個個的取出添加,這樣既保持了原理的寫法,也同時兼容了多個ID的傳人。
fileElementId: 'fileID',//這是原始的使用方法,一次傳人一個值 fileElementId:['file1','file2','file3'],//這個是新的寫法,一個數組的形式
這樣就完成了我們的需求啦~那么今天的記錄就到這里了~其實這些都已經是爛大街的東西了,很多地方都有說明了,我在這里記錄的並不僅僅是如何去使用,而且我踩坑的這次過程,如何思考,如何去想解決辦法~o(╯□╰)o希望以后能像這些前輩一樣早發現早治療了~