Just a Computer Graphics Studio & My Life

[Node] 實作Web應用

既然已經在安裝好Node.js,就立馬來開發Web應用,透過Manuel Kiessling大大的帶領,將一步一腳印搭建上傳圖片到server的應用。

nodejs

真沒想到有如此淺顯易懂的教學文章,還能被四個中國開發者翻譯成中文,造福所有想要入門Node.js的新手,在此特別感謝該篇文章!讓我在一天之內馬上體驗,原來Javascript也能寫後端!

安裝的過程可以參考文章:Mac 安裝 Node.js

首先來看我實現後的結果,如此一來就更有信心啦~

一開始的介面:

Node 實作Web應用

上傳影像後的結果:

Node 實作Web應用2

總共有四個js檔:

  • index.js
  • server.js
  • router.js
  • requestHandlers.js

看名字就知道各負責什麼樣的職責,而index.js則是網頁執行的首頁,會引用另三個js檔為自訂模組來使用,其實就是類別的概念。

寫好後在終端機打指令:

node index.js

開啟瀏覽器輸入網址列:

http://localhost:8888/

就會出現上面的圖那個要你上傳影像的介面。

程式碼建議跟著教學逐一實作,來瞭解伺服器端JavaScript、函數編程、Blocking與Non-Blocking、回呼(callback)、事件、內部和外部模組等等。

index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
handle["/show"] = requestHandlers.show;

server.start(router.route, handle);

server.js

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    route(handle, pathname, response, request);
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

router.js

function route(handle, pathname, response, request) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === 'function') {
    handle[pathname](response, request);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/html"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;

requestHandlers.js

var querystring = require("querystring"),
    fs = require("fs"),
    formidable = require("formidable");

function start(response) {
  console.log("Request handler 'start' was called.");

  var body = '<html>'+
    '<head>'+
    '<meta http-equiv="Content-Type" content="text/html; '+     'charset=UTF-8" />'+
    '</head>'+
    '<body>'+
    '
<form action="/upload" enctype="multipart/form-data" '+     'method="post">'+
    '<input type="file" name="upload" multiple="multiple">'+
    '<input type="submit" value="Upload file" />'+
    '</form>

'+
    '</body>'+
    '</html>';

    response.writeHead(200, {"Content-Type": "text/html"});
    response.write(body);
    response.end();
}

function upload(response, request) {
  console.log("Request handler 'upload' was called.");

  var form = new formidable.IncomingForm();
  console.log("about to parse");
  form.parse(request, function(error, fields, files) {
    console.log("parsing done");
    fs.renameSync(files.upload.path, "./tmp/test.png");
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write("received image:
");
    response.write("<img src='/show' />");
    response.end();
  });
}

function show(response) {
  console.log("Request handler 'show' was called.");
  fs.readFile("./tmp/test.png", "binary", function(error, file) {
    if(error) {
      response.writeHead(500, {"Content-Type": "text/plain"});
      response.write(error + "\n");
      response.end();
    } else {
      response.writeHead(200, {"Content-Type": "image/png"});
      response.write(file, "binary");
      response.end();
    }
  });
}

exports.start = start;
exports.upload = upload;
exports.show = show;

看起來程式碼不算多,然而裡頭學問可非常豐富,才一天的時間就讓人很興奮想要繼續學習更多的知識與技術。

原文章裡的程式碼有小bug,修好後就能在該路徑資料夾看到我們上傳的影像喔!

參考:

 

廣告

Comments on: "[Node] 實作Web應用" (1)

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: