formidable 模塊化開發 代碼拆分(解耦) nodejs圖片服務器架構

引言:程序要作到:健壯性、低耦合、可擴展、方便程序員分工合做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()方法暴露出去,以便其餘模塊調用

 

.

相關文章
相關標籤/搜索