這篇文章主要介紹了在Node.js中使用HTTP上傳文件的方法,作者以windows下的visual studio作為操作node的環境,推薦閱讀!需要的朋友可以參考下
開發環境
我們將使用 Visual Studio Express 2013 for Web 作為開發環境, 不過它還不能被用來做 Node.js 開發。為此我們需要安裝 Node.js Tools for Visual Studio。 裝好後 Visual Studio Express 2013 for Web 就會轉變成一個 Node.js IDE 環境,提供創建這個應用所需要的所有東西.。而基於這裡提供的指導,我們需要:
下載安裝 Node.js Windows 版,選擇適用你系統平台的版本, Node.js (x86) 或者Node.js (x64) 。
下載並安裝 Node.js 的 Visual Studio 工具。
安裝完成後我們就會運行 Visual Studio Express 2013 for Web, 並使用 Node.js 的交互窗口來驗證安裝. Node.js 的交互窗口可以再 View->Other Windows->Node.js Interactive Window 下找到. Node.js 交互窗口運行後我們要輸入一些命令檢查是否一切OK.
Figure 1 Node.js Interactive Window
現在我們已經對安裝進行了驗證,我們現在就可以准備開始創建支持GB級文件上傳的Node.js後台程序了. 開始我們先創建一個新的項目,並選擇一個空的 Node.js Web應用程序模板.
Figure 2 New project using the Blank Node.js Web Application template
項目創建好以後,我們應該會看到一個叫做 server.js 的文件,還有解決方案浏覽器裡面的Node包管理器 (npm).
圖3 解決方案管理器裡面的 Node.js 應用程序
server.js 文件裡面有需要使用Node.js來創建一個基礎的hello world應用程序的代碼.
Figure 4 The Hello World application
我現在繼續把這段代碼從 server.js 中刪除,然後在Node.js中穿件G級別文件上傳的後端代碼。下面我需要用npm安裝這個項目需要的一些依賴:
Express - Node.js網頁應用框架,用於構建單頁面、多頁面以及混合網絡應用
Formidable - 用於解析表單數據,特別是文件上傳的Node.js模塊
fs-extra - 文件系統交互模塊
圖5 使用npm安裝所需模塊
模塊安裝完成後,我們可以從解決方案資源管理器中看到它們。
圖6 解決方案資源管理器顯示已安裝模塊
下一步我們需要在解決方案資源管理器新建一個 "Scripts" 文件夾並且添加 "workeruploadchunk.js" 和 "workerprocessfile.js" 到該文件夾。我們還需要下載jQuery 2.x 和 SparkMD5 庫並添加到"Scripts"文件夾。 最後還需要添加 "Default.html" 頁面。
創建Node.js後台
首先我們需要用Node.js的"require()"函數來導入在後台上傳G級文件的模塊。注意我也導入了"path"以及"crypto" 模塊。"path"模塊提供了生成上傳文件塊的文件名的方法。"crypto" 模塊提供了生成上傳文件的MD5校驗和的方法。
?
1
2
3
4
5
6// The required modules
var express = require('express');
var formidable = require('formidable');
var fs = require('fs-extra');
var path = require('path');
var crypto = require('crypto');
下一行代碼就是見證奇跡的時刻。
復制代碼 代碼如下:
var app = express();
這行代碼是用來創建express應用的。express應用是一個封裝了Node.js底層功能的中間件。如果你還記得那個由Blank Node.js Web應用模板創建的"Hello World" 程序,你會發現我導入了"http"模塊,然後調用了"http.CreateServer()"方法創建了 "Hello World" web應用。我們剛剛創建的express應用內建了所有的功能。
現在我們已經創建了一個express應用,我們讓它呈現之前創建的"Default.html",然後讓應用等待連接。
?
1
2
3
4
5
6
7
8// Serve up the Default.html page
app.use(express.static(__dirname, { index: 'Default.html' }));
// Startup the express.js application
app.listen(process.env.PORT || 1337);
// Path to save the files
var uploadpath = 'C:/Uploads/CelerFT/';
express應用有app.VERB()方法,它提供了路由的功能。我們將使用app.post()方法來處理"UploadChunk" 請求。在app.post()方法裡我們做的第一件事是檢查我們是否在處理POST請求。接下去檢查Content-Type是否是mutipart/form-data,然後檢查上傳的文件塊大小不能大於51MB。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// Use the post method for express.js to respond to posts to the uploadchunk urls and
// save each file chunk as a separate file
app.post('*/api/CelerFTFileUpload/UploadChunk*', function(request,response) {
if (request.method === 'POST') {
// Check Content-Type
if (!(request.is('multipart/form-data'))){
response.status(415).send('Unsupported media type');
return;
}
// Check that we have not exceeded the maximum chunk upload size
var maxuploadsize =51 * 1024 * 1024;
if (request.headers['content-length']> maxuploadsize){
response.status(413).send('Maximum upload chunk size exceeded');
return;
}
一旦我們成功通過了所有的檢查,我們將把上傳的文件塊作為一個單獨分開的文件並將它按順序數字命名。下面最重要的代碼是調用fs.ensureDirSync()方法,它使用來檢查臨時目錄是否存在。如果目錄不存在則創建一個。注意我們使用的是該方法的同步版本。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// Get the extension from the file name
var extension =path.extname(request.param('filename'));
// Get the base file name
var baseFilename =path.basename(request.param('filename'), extension);
// Create the temporary file name for the chunk
var tempfilename =baseFilename + '.'+
request.param('chunkNumber').toString().padLeft('0', 16) + extension + ".tmp";
// Create the temporary directory to store the file chunk
// The temporary directory will be based on the file name
var tempdir =uploadpath + request.param('directoryname')+ '/' + baseFilename;
// The path to save the file chunk
var localfilepath =tempdir + '/'+ tempfilename;
if (fs.ensureDirSync(tempdir)) {
console.log('Created directory ' +tempdir);
}
正如我之前提出的,我們可以通過兩種方式上傳文件到後端服務器。第一種方式是在web浏覽器中使用FormData,然後把文件塊作為二進制數據發送,另一種方式是把文件塊轉換成base64編碼的字符串,然後創建一個手工的multipart/form-data encoded請求,然後發送到後端服務器。
所以我們需要檢查一下是否在上傳