nodejs入門學習筆記一——一個完整的http路由服務實現


  開始學習nodejs!

  參考書籍:The Node Beginner Book ,所有問題和討論都圍繞本書。

  1.學習nodejs需要具備的基礎知識:

  js基本語法,基本上寫過前端的都能滿足,原生js、jquery

  2.nodejs與基礎知識相比,學習的點在哪里?

  nodejs本身就是js,如下:

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

  nodejs使用模塊化編程

    關於模塊化,只要知道它解決什么問題即可:

      模塊化其實就是封裝,把一組特定功能的代碼封裝在一個類似java jar包的模塊中,方便復用,使結構清晰,等等

      js從原生的順序無模塊代碼,到自執行函數、jquery匿名函數、到CommonJS,就是一個模塊化進程,習慣使用jquery的童鞋不應該抵觸新的模塊化編程

    nodejs的模塊化,我們都要學習哪些?

      1.使用現成模塊工具

        如上代碼,copy到server.js中,cmd命令下執行   node server.js

        訪問 http://localhost:8888/  ,一個簡單的web服務就成功訪問了!

        這里使用   require("http") 調用http模塊,這個是nodejs內置的

      2.自己封裝模塊

        server.js可能我們會加入更多其他的路由代碼,這時候我們可以把啟動功能遷移出去,如何辦?

        

var http = require("http");

function start() {
  function onRequest(request, response) {
    console.log("Request received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

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

exports.start = start;

        server.js修改一下,把啟動web服務器的代碼移到start方法體中,

      使用  exports.start = start  向外部暴露web啟動方法

      習慣上,我們使用index.js來啟動app,代碼如下:

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

server.start();

 

      執行 node index.js  效果一樣!

  3.完善web服務器的路由功能

    可以發現,訪問8888的任意資源都會返回helloworld,why?

    這就說明我們這個服務器其實是缺少路由功能的,也可以說,路由功能使用基本的if else即可實現,我們先獲取request請求路徑

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

function start() {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

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

exports.start = start;

 

    使用url即可獲取資源請求路徑。

    習慣上,使用router.js來負責路由分發:

function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

    server.js 導入route模塊,  start方法調用route方法即可,

    當然,route其實應該作為服務器的一個組件傳入進去,我們可以這樣:

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

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

    route(pathname);

    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

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

exports.start = start;

    而index.js相應的:

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

server.start(router.route);

    事實上,我們現在的路由器還未有任何處理請求的功能,而根據經驗,處理各種請求,應該有對應的程序塊,

  如果在rout方法體中使用if else,那么代碼結構將會極其丑陋

  js的函數式編程給了我們一個啟示——可以將不同的請求封裝在一個requestHandler中,然后暴露出來供route調用:

  requestHandlers.js

  

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

function upload() {
  console.log("Request handler 'upload' was called.");
}

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

  index.js入口腳本來載入handler

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;

server.start(router.route, handle);

    handler就是一個字典,針對不同請求,執行不同的處理邏輯

    相應改變的,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.writeHead(200, {"Content-Type": "text/plain"});
    response.write("Hello World");
    response.end();
  }

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

exports.start = start;

    router.js

function route(handle, pathname) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === 'function') {
    handle[pathname]();
  } else {
    console.log("No request handler found for " + pathname);
  }
}

exports.route = route;

    至此,一個簡單的路由功能就優雅的實現了!

    路由功能實現了,但是每個請求響應全都是hello world,這個處理起來也不復雜,只需要讓handler返回結果,然后response將結果輸出出去即可!



  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM