jQuery的ajax中使用FormData實(shí)現(xiàn)頁(yè)面無(wú)刷新上傳功能
接著上一篇ajax系列之用jQuery的ajax方法向服務(wù)器發(fā)出get和post請(qǐng)求寫(xiě),這篇主要寫(xiě)如何利用ajax和FormData實(shí)現(xiàn)頁(yè)面無(wú)刷新的文件上傳效果,主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData接口。關(guān)于FormData,大家可以看MDN文檔。
1,先看效果圖
期望的功能和效果很簡(jiǎn)單:點(diǎn)擊頁(yè)面中的上傳文件表單控件,選擇文件后點(diǎn)擊“ajax提交”,將文件上傳至服務(wù)器,上傳成功后,頁(yè)面給出一個(gè)簡(jiǎn)單的提示。
2,前端的代碼
看下html代碼:
<div class="box"> <div> <div class="item"> <input type="file" name="myfile" style="font-size: 0.7rem;"> </div> <div class="item"> <button type="button" style="display: block; padding: 4px 18px;" class="btn-default">ajax提交</button> </div> <div class="item"> <button type="submit" style="display: block; padding: 4px 18px;" class="btn-default">form提交</button> </div> </div> <div class="prompt" style="font-size: 0.7rem;"></div> </div> <script src="../../js/jquery-3.1.0.min.js"></script> <script src="upload01.js"></script>
代碼很簡(jiǎn)單,需要注意的是頁(yè)面中沒(méi)有用到form表單,那么怎么提交數(shù)據(jù)呢,答案是用FormData來(lái)模擬表單中的 <input type="file" name="myfile"> 控件。另外,頁(yè)面中的樣式?jīng)]有寫(xiě)出來(lái)。下面來(lái)看下html中引入的upload01.js代碼,這個(gè)是重點(diǎn)。
upload01.js代碼:
$(function($) { $('input[name=myfile]').on('change', function(e) { $('button[type=button]').on('click', function(e) { var formData = new FormData(); // formData.ppend(name, element); formData.append('myfile', $('input[name=myfile]')[0].files[0]); $.ajax({ url: 'upload.php', method: 'POST', data: formData, contentType: false, // 注意這里應(yīng)設(shè)為false processData: false, cache: false, success: function(data) { if (JSON.parse(data).result == 1) { $('.prompt').html(`文件${JSON.parse(data).filename}已上傳成功`); } }, error: function (jqXHR) { console.log(JSON.stringify(jqXHR)); } }) .done(function(data) { console.log('done'); }) .fail(function(data) { console.log('fail'); }) .always(function(data) { console.log('always'); }); }); }); });
(1) 下面解釋下FormData,涉及到了代碼的第4、6、10行。
第4行 var formData = new FormData();
實(shí)例化了一個(gè)空的FormData對(duì)象,可以認(rèn)為它就是一個(gè)form表單,但現(xiàn)在里面什么控件都沒(méi)有。
第6行 formData.append('myfile', $('input[name=myfile]')[0].files[0]);
,給實(shí)例化的formdata對(duì)象添加一個(gè)控件,注意這里添加的是已有控件 <input type="file" name="myfile" style="font-size: 0.7rem;">
(見(jiàn)html代碼第4行)。
FormData.append(name, value, filename)
方法可以很方便的以“鍵-值”對(duì)的形式給FormData添加控件,注意第3個(gè)參數(shù)“上傳文名”是可選的,它的具體語(yǔ)法和用法見(jiàn)FormData。
第10行,將實(shí)例化的formData作為jQuery.ajax()方法data參數(shù)的值傳遞進(jìn)去,提交給后端服務(wù)器。
(2) 再解釋下ajax()方法中的contentType、processData參數(shù)。
contentType參數(shù),發(fā)起http請(qǐng)求時(shí)設(shè)置的請(qǐng)求頭中的contentType。jQuery.ajax()默認(rèn)的值為:'application/x-www-form-urlencoded; charset=UTF-8',這個(gè)在大多數(shù)情況下都是適用的。
但經(jīng)過(guò)測(cè)試,保持默認(rèn)時(shí)會(huì)報(bào)錯(cuò),因?yàn)榘l(fā)送的數(shù)據(jù)中有input type="file"(上傳文件),那么這時(shí)contentType應(yīng)該設(shè)置為'multipart/form-data',但如果指定為這個(gè)類(lèi)型服務(wù)端(php)就會(huì)報(bào)這個(gè)錯(cuò)誤: Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 。具體原因現(xiàn)在還不清楚,所以這里先將contentType設(shè)置為false,即不讓jQuery設(shè)置contentType。
processData參數(shù),根據(jù)jQuery.ajax()文檔中的解釋?zhuān)J(rèn)情況下,jQuery會(huì)處理發(fā)送的數(shù)據(jù),將數(shù)據(jù)按照'application/x-www-form-urlencoded'的要求轉(zhuǎn)換為查詢(xún)字符串,如果要發(fā)送的數(shù)據(jù)是DOMDocument或者不需要處理,就可以設(shè)置為false不讓jQuery轉(zhuǎn)換數(shù)據(jù),我們這里要發(fā)送的數(shù)據(jù)其實(shí)就是DOMDocument。
經(jīng)過(guò)測(cè)試,如果保持默認(rèn)(true)的話(huà),在發(fā)起請(qǐng)求前js會(huì)報(bào)錯(cuò): TypeError: 'append' called on an object that does not implement interface FormData.
另外還有個(gè)dataType參數(shù),期望從服務(wù)器中返回的數(shù)據(jù)格式,這里最好也不要指定,而是讓jquery自己根據(jù)http響應(yīng)頭中的contentType判斷,然后返回一個(gè)合適的數(shù)據(jù)類(lèi)型。指定后不會(huì)影響后臺(tái)程序的邏輯處理,但你在前端接收的數(shù)據(jù)很可能不是期望的數(shù)據(jù),于是js就會(huì)報(bào)這一類(lèi)錯(cuò)誤: SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data ,這個(gè)是將dataType指定為json后報(bào)的錯(cuò)誤。
3,后端的php代碼
后端服務(wù)器是nginx,用php來(lái)處理發(fā)送過(guò)來(lái)的數(shù)據(jù),代碼也很簡(jiǎn)單:
<?php // var_dump($_REQUEST); // 為空數(shù)組 // var_dump($_FILES); //不為空 // 當(dāng)使用FormData配合ajax上傳文件時(shí),$_REQUEST、$_POST都是null,php://input也是null if (isset($_FILES) && !empty($_FILES)) { if (move_uploaded_file($_FILES['myfile']['tmp_name'], $_FILES['myfile']['name'])) { echo '{"result": 1, "filename": "' . $_FILES['myfile']['name'] . '"}'; } else { echo '{"result": 0}'; } }
代碼的邏輯很簡(jiǎn)單這里就不多解釋了。主要說(shuō)下我在調(diào)試程序時(shí)遇到的問(wèn)題,遇到的問(wèn)題總結(jié)起來(lái)就一句話(huà):當(dāng)使用FormData配合ajax上傳文件時(shí),$_REQUEST、$_POST都是空數(shù)組,php://input也是null??梢钥吹?,我在代碼中的第2、3、5行也寫(xiě)了相關(guān)的注釋。為什么$_REQUEST會(huì)是空呢?我查了些資料,但沒(méi)找到原因,以后再找原因吧。
以上所述是小編給大家介紹的jQuery的ajax中使用FormData實(shí)現(xiàn)頁(yè)面無(wú)刷新上傳功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
jquery實(shí)現(xiàn)通用的內(nèi)容漸顯Tab選項(xiàng)卡效果
這篇文章主要介紹了jquery實(shí)現(xiàn)通用的內(nèi)容漸顯Tab選項(xiàng)卡效果,涉及jquery通過(guò)時(shí)間函數(shù)定時(shí)觸發(fā)頁(yè)面元素樣式變換的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09jquery 查找select ,并觸發(fā)事件的實(shí)現(xiàn)代碼
項(xiàng)目中,用jquery 查找select ,并觸發(fā)事件. 記一筆.關(guān)鍵代碼,需要的朋友可以參考下。2011-03-03jQuery插件zTree實(shí)現(xiàn)更新根節(jié)點(diǎn)中第i個(gè)節(jié)點(diǎn)名稱(chēng)的方法示例
這篇文章主要介紹了jQuery插件zTree實(shí)現(xiàn)更新根節(jié)點(diǎn)中第i個(gè)節(jié)點(diǎn)名稱(chēng)的方法,結(jié)合實(shí)例形式分析了樹(shù)形插件zTree針對(duì)節(jié)點(diǎn)的更新操作相關(guān)技巧,需要的朋友可以參考下2017-03-03用jquery實(shí)現(xiàn)的一個(gè)超級(jí)簡(jiǎn)單的下拉菜單
這篇文章主要介紹了用jquery實(shí)現(xiàn)的一個(gè)超級(jí)簡(jiǎn)單的下拉菜單,需要的朋友可以參考下2014-05-05jquery+css3實(shí)現(xiàn)的經(jīng)典彈出層效果示例
這篇文章主要介紹了jquery+css3實(shí)現(xiàn)的經(jīng)典彈出層效果,結(jié)合實(shí)例形式分析了jquery+css3實(shí)現(xiàn)彈出層具體原理、步驟與相關(guān)操作技巧,需要的朋友可以參考下2020-05-05jquery實(shí)現(xiàn)標(biāo)簽支持圖文排列帶上下箭頭按鈕的選項(xiàng)卡
這篇文章主要介紹了jquery實(shí)現(xiàn)標(biāo)簽支持圖文排列帶上下箭頭按鈕的選項(xiàng)卡的特效,效果十分不錯(cuò),而且非常實(shí)用,有需要的小伙伴參考下吧。2015-03-03Jquery下的26個(gè)實(shí)用小技巧(jQuery tips, tricks & solutions)
前段時(shí)間發(fā)布了Jquery類(lèi)庫(kù)1.4版本,使用者也越來(lái)越多,為了方便大家對(duì)Jquery的使用,下面列出了一些Jquery使用技巧。2010-03-03jQuery實(shí)現(xiàn)html table行Tr的復(fù)制、刪除、計(jì)算功能
這篇文章主要介紹了jQuery實(shí)現(xiàn)html table行Tr的復(fù)制、刪除、計(jì)算功能,涉及jQuery針對(duì)table表格的常見(jiàn)復(fù)制、添加、刪除與計(jì)算行數(shù)等簡(jiǎn)單操作技巧,需要的朋友可以參考下2017-07-07