H5拖放+FormData接口+NodeJS,完整異步文件上傳(一)

  前段時間面試過程當中,頻繁遇到H5異步文件上傳的相關問題。還遇到過一個"經過H5拖放功能實現文件異步上傳"的問題,大概知道H5有新增拖拽功能能夠接收文件,如何異步上傳文件就母雞了(攤手)。面試結束後,特地去看了相關知識點,瞭解到H5拖放+FormData接口能夠實現異步上傳。爲了測試文件上傳是否成功,還去看了Node.js如何接收異步文件上傳。因此,這會是一個H5拖放+FormData接口+Node.js實現文件異步上傳的完整Demo。
  先簡單介紹一下這幾個知識點,貼上詳細介紹的連接,有興趣的同窗能夠點進去多瞭解一些。javascript

HTML5 拖放

  拖放(Drag 和 drop)是 HTML5 標準的組成部分。拖放是一種常見的特性,即抓取對象之後拖到另外一個位置。抓取的對象能夠是頁面中DOM元素(須要設置draggable="true")或者系統文件。監聽放置元素的drop事件,經過DataTransfer對象能夠得到拖拽事件的狀態及數據。詳情可查閱MDN的HTML5 拖放 API文檔css

FormData 接口

  XMLHttpRequest Level 2添加了一個新的接口FormData。利用FormData對象,咱們能夠經過JavaScript用一些鍵值對來模擬一系列表單控件,咱們還可使用XMLHttpRequest的send()方法來異步的提交這個"表單"。比起普通的ajax,使用FormData的最大優勢就是咱們能夠異步上傳一個二進制文件。詳情可查閱MDN的FormData接口文檔html

後端文件接收&保存

  後端使用Node.js+Express+Multer實現文件上傳。Express基於 Node.js平臺,快速、開放、極簡的web開發框架。Multer 是一個 node.js 中間件,用於處理 multipart/form-data 類型的表單數據,它主要用於上傳文件。java

小二,上代碼

新建drop.html,插入如下代碼 node

HTML代碼: 先添加一個放置的div,而且監聽ondrop和ondragover事件。git

<div class="drop-area"  ondrop="drop_hander(event)" ondragover = "dragover_hander(event)"></div>

樣式代碼: 加個邊框,設置一下大小。github

.drop-area{
    margin:auto;
    width: 500px;
    height: 500px;
    border:1px pink dashed;
}

JavaScript代碼: 監聽拖放事件,獲取文件,建立XHR實例併發送請求web

/* 拖動到放置區域時 */
function dragover_hander (event) {
    /* 必須同時阻止dragover和drop的默認事件
       不然會響應瀏覽器默認行爲
       瀏覽器能顯示的文件會直接顯示,例如html文件、圖片文件
       瀏覽器不能顯示的文件會出現文件下載彈窗
    */
    event.preventDefault(); 
}

/*拖放完成事件*/
function drop_hander (event) {

    event.preventDefault(); //阻止默認事件

    var files = event.dataTransfer.files; //經過dataTransfer對象獲取文件對象數組
    var formData = new FormData(); //聲明一個FormData實例

    for(var i = 0, len = files.length; i < len; i++) {
        //使用append方法添加文件到file鍵
        formData.append('file',  files[i]);
    }

    var request = new XMLHttpRequest(); //建立XHR實例
    request.open('POST', '/process_post'); //初始化請求
    request.send(formData);//發送請求
}

新建formupload.js,寫服務端代碼:使用express建立服務,使用multer中間保存文件。 這裏須要安裝express和multer依賴包。這裏默認你已經有簡單瞭解Node.js,會使用npm安裝依賴包。若是還沒接觸過,能夠看看菜鳥教程的Node.js 教程,看完前四節就行。面試

const express = require('express'); //引入express模塊
const app = express(); //建立一個express應用
const multer = require('multer'); // 引入multer模塊

/*
 新建一個multer中間件,設置文件保存路徑
 路徑必須存在,不然會報錯
*/
const upload = multer({ dest: 'uploads/' }); 

/* 請求/drop.html,返回文件 */
app.get('/drop.html', function (req, res) {
   res.sendFile( __dirname + "/" + "drop.html" );
})

/* 
建立提交接口
使用中間件處理
upload.array('file')表示上傳一個名爲file文件數組
 */
app.post('/process_post', upload.array('file'), function (req, res,next) {
 
  if (!req.files) { // 末上傳文件的返回
    res.json({ ok: false });
    return;
  }
  //有上傳文件,返回文件列表
  res.json(req.files) 
  return;
})

//啓動服務,監聽8081端口
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應用實例,訪問地址爲 http://%s:%s", host, port)
 
})

到這裏代碼就結束了,下面是目錄結構。完整代碼能夠查看項目github地址注意:uploads文件夾必定要存在,不然服務會報錯ajax

h5-drop-upload
|- /uploads
|- drop.html
|- formupload
|- package.json

打開命令行,在h5-drop-upload目錄下執行:

node formupload.js

若是沒報錯,會輸出:

應用實例,訪問地址爲 http://:::8081

打開瀏覽器,輸入:127.0.0.1:8081/drap.html。而後拖動文件到粉紅色的框中,查看upload文件夾,你上傳的文件就會這裏(爲了不命名衝突,Multer 會修改上傳的文件名)。到了這裏還沒報錯,就表示整個「H5拖放+FormData接口+Node.js」文件上傳的Demo已經跑通了,能夠結本身鼓掌了。

鼓掌

結束語

  咱們已經簡單實現文件異步上傳功能,但離實際使用場景還有差距。實際使用中,確定不能拖放完成就立刻上傳,至少應該顯示一個文件列表,用戶能夠增刪文件,最後確認再開始上傳。更進一步,最好能夠給個進度條,顯示文件上傳進度。接下來,讓咱們繼續完善,敬請期待下篇。

  若是你已經看這裏,麻煩順便點個贊咯。。。。

相關文章
相關標籤/搜索