引言:程序要作到:健壯性、低耦合、可擴展、方便程序員分工合做javascript
上傳圖片值nodejs服務器並顯示圖片的源代碼:html
post.html :java
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>圖片上傳</title> </head> <body> <!-- form表單: action 向何處發送表單數據(url) method 方法 enctype 上傳類型 --> <form action="/upload" method="post" enctype="multipart/form-data"> <!--描述--> <input type="text" name="description"> <!--上傳圖片--> <input type="file" name="myFile"> <!--提交按鈕--> <input type="submit" value="點擊提交"> </form> </body> </html>
formidable_upload.js :node
/** * 使用插件前,須要配置環境 npm install formidable * 擴展應用,使得上傳到服務器的圖片能夠顯示 */ var formidable = require('formidable'); var http = require('http'); var util = require('util'); // 1.http 和 util 是nodejs的內核模塊,不須要單獨安裝 var fs = require('fs'); // 4.引入文件模塊fs // 16.建立模塊,定義函數封裝 function start() { // 17.調用start()方法,啓動HTTP服務器 // 定義onRequest方法,接收並處理HTTP請求的 function onRequest(request, response) { // 經過http模塊建立一個服務器(http服務器) if (request.url === '/upload' && request.method.toLowerCase() === 'post') { // 對上傳路徑進行判斷 // 針對圖片上傳進行處理 // 解析上傳文件 var form = new formidable.IncomingForm(); form.uploadDir = "public/upload/"; // 10.設置圖片上傳路徑 form.parse(request, function(err, fields, files) { fs.renameSync(files.myFile.path,"tmp/test.png"); // 11.文件搬移(覆蓋"tmp/test.png") response.writeHead(200, {'content-type': 'text/html'}); // 12.響應一個頁面 response.write('received image:<br/>'); response.write("<img src='/show'>"); // 13.將圖片展現出來 response.end(); }); return; } else if(request.url === '/show') { // 3.擴展應用,使得上傳到服務器的圖片能夠顯示 // 調試 console.log("request for show is received"); // 5.經過文件模塊fs,將圖片寫入響應 fs.readFile("tmp/test.png","binary",function(error, file) { if(error){ // 6.讀取失敗 response.writeHead(500, {'content-type': 'text/plain'}); // writeHead自請求頭 能夠寫回請求頭 console.log(error); response.write('500 服務器內部錯誤'); response.end(); } else { // 7.讀取數據成功 response.writeHead(200, {'content-type': 'image/png'}); // content-type 返回的文件格式 response.write(file,"binary"); // 將文件以二進制的方式寫到頁面上 response.end(); } }); // 讀取文件readFile("文件","讀取方式 binary二進制",回調函數 經過回調函數進行響應) return; } // 展現上傳文件表單 var body = fs.readFileSync('./post.html');// 8.使用post.html替換掉固有的表單結構(response.end) response.writeHead(200, {'content-type': 'text/html'}); response.write(body); response.end(); // response.end( // '<form action="/upload" enctype="multipart/form-data" method="post">'+ // '<input type="text" name="title"><br>'+ // '<input type="file" name="upload" multiple="multiple"><br>'+ // '<input type="submit" value="Upload">'+ // '</form>' // ); } http.createServer(onRequest).listen(80,function(){ //15.將onRequest做爲參數傳到createServer()方法中 // 9.設置服務器返回信息 console.log("Server is starting on port 80."); }); // 2.改爲web默認端口 80 } exports.start = start;// 18.將start()方法暴露出去,以便外部調用
將formidable_upload.js進行優化 及 模塊化開發:程序員
index.js :web
var server = require('./server.js'); server.start();
server.js :npm
/** * 主文件 * 使用插件前,須要配置環境 npm install formidable * 擴展應用,使得上傳到服務器的圖片能夠顯示 */ var http = require('http'); var url = require('url');// 20.引入url模塊 var router = require('./router.js'); // 23.引入router.js // 16.建立模塊,定義函數封裝 function start() { // 17.調用start()方法,啓動HTTP服務器 // 定義onRequest方法,接收並處理HTTP請求的 function onRequest(request, response) { // 經過http模塊建立一個服務器(http服務器) // // 方法一 // if(request.url === '/aaa'){} // else if(request.url === '/bbb'){} // ... // // 方法二 // switch (request.url) { // case 'aaa': // break; // default: // } // 19.方法三:定義一個函數,並暴露給其餘模塊調用 router.route(request, response); // 21.調用route()方法, pathname請求 response響應 } http.createServer(onRequest).listen(80,function(){ //15.將onRequest做爲參數傳到createServer()方法中 // 9.設置服務器返回信息 console.log("Server is starting on port 80."); }); // 2.改爲web默認端口 80 } exports.start = start;// 18.將start()方法暴露出去,以便其餘模塊調用
router.js :服務器
// 文件的處理 及 第三方插件的引用 代碼拆分 var util = require('util'); // 1.http 和 util 是nodejs的內核模塊,不須要單獨安裝 var url = require('url'); // 25.引入url模塊 var requestHandler = require('./requestHandler.js'); // 41.引入requestHandler.js模塊 var handle = requestHandler.handle; // 42.定義handle對象,並賦值 // 20.封裝route函數進行請求的處理 function route(request, response){ // 經過route進行轉發、響應 // 24.將request總體引入,在route下進行統一的處理 var pathname = url.parse(request.url).pathname; // 判斷需求 if(typeof(handle[pathname]) === "function"){ console.log("about to route to handle" + pathname); // 交給具體的請求程序執行 // 判讀handle[pathname]的類型是方法,則執行這個方法 handle[pathname](request, response); } else { // 38.特殊狀況處理 console.log(pathname); response.writeHead(404, {'content-type': 'text/plain'}); response.write("404, Not Found."); response.end(); } // if (pathname === '/upload' && request.method.toLowerCase() === 'post') { // 對上傳路徑進行判斷 // console.log("request for upload is received. 請求已收到."); // console.log("about to route to upload Handle 路由給upload請求處理函數."); // uploadHandler.upload(request, response); // 27.調用uploadHandler()方法 // } else if(pathname === '/show') { // 3.擴展應用,使得上傳到服務器的圖片能夠顯示 // // 調試 // console.log("request for show is received"); // console.log("about to route to show Handle 路由給show請求處理函數."); // showHandler.show(request, response);// 31.調用show()方法 // } else if(pathname === '/start') { // 33.建立上傳點 // // 調試 // console.log("request for start is received"); // console.log("about to route to start Handle 路由給start請求處理函數."); // startHandler.start(request, response); // 35.調用start()方法 // } else { // // 38.特殊狀況處理 // console.log(pathname); // response.writeHead(404, {'content-type': 'text/plain'}); // response.write("404, Not Found."); // response.end(); // } } exports.route = route;// 22.將route()方法暴露出去,以便其餘模塊調用
requestHandler.js :模塊化
/** * 40.路由表/服務單 */ var uploadHandler = require('./uploadHandler.js'); // 29.引入uploadHandler.js模塊 var showHandler = require('./showHandler.js'); // 32.引入showHandler.js模塊 var startHandler = require('./startHandler.js'); // 36.引入startHandler.js模塊 // 39.經過對象取值的方式,替換掉if else // 定義handle對象,用來保存 請求與請求處理函數 的關係 var handle = {}; handle['/upload'] = uploadHandler.upload; handle['/show'] = showHandler.show; handle['/start'] = startHandler.start; handle['/'] = startHandler.start;// 根目錄 exports.handle = handle;// 暴露路由表對象handle,以便其餘模塊調用
startHandler.js :函數
/** * 上傳點 */ var fs = require('fs');// 37.引入文件模板fs // 34.定義start(),封裝具體的處理方法 function start(request, response) { // 展現上傳文件表單 var body = fs.readFileSync('./post.html');// 8.使用post.html替換掉固有的表單結構(response.end) response.writeHead(200, {'content-type': 'text/html'}); response.write(body); response.end(); // response.end( // '<form action="/upload" enctype="multipart/form-data" method="post">'+ // '<input type="text" name="title"><br>'+ // '<input type="file" name="upload" multiple="multiple"><br>'+ // '<input type="submit" value="Upload">'+ // '</form>' // ); } exports.start = start;// 將start()方法暴露出去,以便其餘模塊調用
uploadHandler.js :
/** * 28.單獨拿出,專門用來處理圖片上傳請求 */ var formidable = require('formidable'); var fs = require('fs'); // 4.引入文件模塊fs // 26.定義uploadHandler,封裝具體的處理方法 function upload(request, response) { // 針對圖片上傳進行處理 // 解析上傳文件 var form = new formidable.IncomingForm(); form.uploadDir = "public/upload/"; // 10.設置圖片上傳路徑 form.parse(request, function(err, fields, files) { fs.renameSync(files.myFile.path,"tmp/test.png"); // 11.文件搬移(覆蓋"tmp/test.png") response.writeHead(200, {'content-type': 'text/html'}); // 12.響應一個頁面 response.write('received image:<br/>'); response.write("<img src='/show'>"); // 13.將圖片展現出來 response.end(); }); return; } exports.upload = upload;// 29.upload()方法暴露出去,以便其餘模塊調用
showHandler.js :
/** * 單獨取出,專門用於圖片展現 */ var fs = require('fs');// 32.引入文件模板fs // 30.定義show()方法,封裝圖片展現的具體實現方法 function show(request, response) { // 5.經過文件模塊fs,將圖片寫入響應 fs.readFile("tmp/test.png","binary",function(error, file) { if(error){ // 6.讀取失敗 response.writeHead(500, {'content-type': 'text/plain'}); // writeHead自請求頭 能夠寫回請求頭 console.log(error); response.write('500 服務器內部錯誤'); response.end(); } else { // 7.讀取數據成功 response.writeHead(200, {'content-type': 'image/png'}); // content-type 返回的文件格式 response.write(file,"binary"); // 將文件以二進制的方式寫到頁面上 response.end(); } }); // 讀取文件readFile("文件","讀取方式 binary二進制",回調函數 經過回調函數進行響應) return; } exports.show = show;// 將show()方法暴露出去,以便其餘模塊調用
.