var express = require('express');// 將檔案命名為 fileServer.js
var app = express( );
app.configure(function() {
app.use(express.bodyParser({uploadDir: './'}));
});
app.listen(8800);
app.get('/upload', function(req, res) {
res.write('<html><body><form method="post" enctype="multipart/form-data" action="/fileUpload">'
+'<input type="file" name="uploadingFile"><br>'
+'<input type="submit">'
+'</form></body></html>');
res.end();
});
如此一來,可以用 Browser 打開 http://127.0.0.1:8800/upload 這樣一來就是執行上方的程式碼
app.get('/upload', function(req, res) {也就是回傳一個 HTML 的內容給 Browser
res.write('<html><body><form method="post" enctype="multipart/form-data" action="/fileUpload">'
+'<input type="file" name="uploadingFile"><br>'
+'<input type="submit">'
+'</form></body></html>');
res.end();
});
<html>在 Firefox 上面會看到
<body>
<form method="post" enctype="multipart/form-data" action="/fileUpload">
<input type="file" name="uploadingFile"><br>
<input type="submit">
</form>
</body>
</html>
這個 submit 按下去之後會去連結 /fileUpload 這個路徑,所以接下來就是要來處理這個 post method。在 fileServer.js 加入以下程式碼
var fs = require('fs');
app.post('/fileUpload', function(req, res) {在這我們會用到檔案處理,所以要require('fs')
var uploadedFile = req.files.uploadingFile;
var tmpPath = uploadedFile.path;
var targetPath = './' + uploadedFile.name;
fs.rename(tmpPath, targetPath, function(err) {
if (err) throw err;
fs.unlink(tmpPath, function() {
console.log('File Uploaded to ' + targetPath + ' - ' + uploadedFile.size + ' bytes');
});
});
res.send('file upload is done.');
res.end();
});
對於上傳檔案來說,express 會用 req.files 來暫存有關上傳檔案的資訊,在這個例子中會看到如下的訊息
{ uploadingFile:
{ size: 15198,
path: '7fedaa5a4b44a499e2cfd29fc7c3be71',
name: 'object.png',
type: 'image/png',
hash: false,
lastModifiedDate: Mon Aug 27 2012 09:06:45 GMT+0800 (CST),
_writeStream:
{ path: '7fedaa5a4b44a499e2cfd29fc7c3be71',
fd: 10,
writable: false,
flags: 'w',
encoding: 'binary',
mode: 438,
bytesWritten: 15198,
busy: false,
_queue: [],
_open: [Function],
drainable: true },
length: [Getter],
filename: [Getter],
mime: [Getter]
}
}
在這個 json 物件裡,第一個出現的 key 是 uploadingFile 也就是寫在 client form 的
<html>上方的 name 之後的值,接著比較重要的是 express 會把收到的 file 放在一個暫存的路徑,寫在 req.files 中的 path 之後,為
<body>
<form method="post" enctype="multipart/form-data" action="/fileUpload">
<input type="file" name="uploadingFile"><br>
<input type="submit">
</form>
</body>
</html>
path: '7fedaa5a4b44a499e2cfd29fc7c3be71',我們接著看 fileServer.js 裡的程式碼
var uploadedFile = req.files.uploadingFile;由 uploadingFile.path 取到的是 tmp 的資料夾,把這裡的東西搬到 targetPath 這裡。前提是 express 要做一個設定
var tmpPath = uploadedFile.path;
var targetPath = './' + uploadedFile.name;
var app = express( );設定 body 中 uploadDir 的真實路徑。
app.configure(function() {
app.use(express.bodyParser({uploadDir: './'}));
});
app.listen(8800);
fs.rename(tmpPath, targetPath, function(err) {利用 fs.rename 把在 tmp 路徑的上傳檔案移到 targetPath 中。最後用 unlink 移除 在 tmpPath 裡的檔案。這樣上傳的 post 就處理完成了。可以上傳看看,會放在和 fileServer.js 同一個目錄。
if (err) throw err;
fs.unlink(tmpPath, function() {
console.log('File Uploaded to ' + targetPath + ' - ' + uploadedFile.size + ' bytes');
});
});
再來處理下載的部分,新增程式碼在 fileServer.js
app.get('/data', function(req,res) {
if (req.query.fileName) {
var filename = req.query.fileName;
console.log(filename);
var mimeType = "image/png";
res.writeHead(200, mimeType);
var fileStream = fs.createReadStream(filename);
fileStream.on('data', function (data) {
res.write(data);
});
fileStream.on('end', function() {
res.end();
});
}else{
res.writeHead(404,{"Content-Type": "application/zip"});
res.write("error");
res.end();
}
});
下載的部分打算用 get 來完成,如果使用者在 Browser 下達
http://127.0.0.1:8800/data?fileName=object.png就是準備要下載 object.png 這個檔案,所以一開始用
if(req.query.fileName)來確定有指定 file name
用
var mimeType = "image/png";來和 Browser 說接下來要傳的是一個 png 檔
res.writeHead(200, mimeType);
var fileStream = fs.createReadStream(filename);上方的部分是開始一個 write stream,然後在 data 的狀態下,利用 res.write() 把資料寫給 Browser。在 end 的時候結束和 browser 的通訊。
fileStream.on('data', function (data) {
res.write(data);
});
fileStream.on('end', function() {
res.end();
});
在 Server 的部分通常會先和 Client 說 Client 想下載的檔案大小如何,請如下指定
fs.stat(filename, function(error, stat) {其中 filename 指的是 request 想要下載的檔案路徑。
if (error) { throw error; }
res.writeHead(200, {
'Content-Type' : 'image/png',
'Content-Length' : stat.size
});
});
如此一來,下載的部分也完成了。一樣,程式碼放在 GitHub。
沒有留言:
張貼留言