Node.js搭建WEB伺服器

來源:互聯網
上載者:User
前言

這幾天為了熟悉vue.js架構,還有webpack的使用,就準備搭建一個發布和瀏覽markdwon的簡單WEB應用。原本是想著用bash指令碼和busybox的httpd來作為後台服務,但是bash指令碼解析和產生JSON非常不方便,而用Java語言寫又覺得部署不方便,所以就想到了正在用到的Node.js,於是就有了這篇博文。(文末有本文代碼的github地址)

簡單例子

首先,從搭建最簡單的Hello world開始,建立以下目錄、檔案和內容。

建立項目及運行

project

  web-server+ | - server.js

server.js

const http = require('http');http.createServer(function(request, response) {  // 設定回應標頭  response.writeHeader(200, {    "Content-Type" : "text/plain"  });  // 響應主體為 "Hello world!"  response.write("Hello world!");  response.end();})// 設定監聽連接埠為9000.listen(9000);

現在,在項目目錄運行下面命令來執行server.js,瀏覽器地址欄中輸入localhost:9000,如果一切訪問都正常,瀏覽器就會顯示Hello world!

node server.js

提示:使用ctrl+c停止指令碼運行。

至此一個簡單例子就運行成功了,下面來分析一下代碼。

程式碼分析

首先,server.js中引入了Node.js的http模組,它提供了非常底層HTTP API支援。這裡使用createServer()方法,它返回一個http.server執行個體,使用該執行個體的listen()方法來設定監聽連接埠。

方法createSever()中填寫的參數是一個函數,該函數會作為回呼函數自動添加到request事件去,其參數類型分別為http.IncomingMessagehttp.ServerResponse。在回呼函數體裡,利用http.ServerResponse的方法設定了回應標頭和響應主體,最後以end()方法結束本次請求。

路由功能

上述的例子僅僅實現了簡單請求響應功能,現在增加路由的功能來健壯我們的WEB伺服器。現在,修改為以下的目錄、檔案和內容。

實現簡單路由

project

  web-server  | - server.js+ | - router.js

server.js

const http = require('http');const router = require('./router.js');function handleHello(request, response) {  // 設定回應標頭  response.writeHeader(200, {    "Content-Type" : "text/plain"  });  // 響應主體為 "Hello world!"  response.write("Hello world!");  response.end();}http.createServer(function(request, response) {  // 註冊路徑和其對應回呼函數  router.register(request, response, [    {      'url': '/hello',      'handler': handleHello    }  ]);})// 設定監聽連接埠為9000.listen(9000);

router.js

const url = require('url');exports.register = function(request, response, mapping) {  // 解析請求路徑  var pathName = url.parse(request.url).pathname;  // 執行相應請求路徑的回呼函數  for(let i = 0, len = mapping.length;i < len;i++) {    if(mapping[i].url === pathName) {      mapping[i].handler(request, response);      return;    }  }  // 請求路徑不存在返回404頁面  response.writeHeader(404, {    "Content-Type" : "text/html"  });  response.end(`    <html>      <head>        <title>NOT FOUND</title>      </head>      <body>        <h1>404 NOT FOUND</h1>      </body>    </html>  `);}

現在,再次執行server.js指令碼,接著瀏覽器訪問localhost:9000\hello會得到Hello world!的結果,而訪問其他路徑則會得到404頁面。

這個功能的核心實現是在router.js中,通過請求路徑的解析,然後根據預先註冊好的mapping數組,找到與之對應的路徑並執行相應的回呼函數。

靜態資源請求

當前的路由功能只能實現回呼函數的執行,而一個WEB伺服器應具有響應靜態資源請求的能力,接下我們繼續來改造它。現在,保持server.js內容不變,只改變router.js中的內容(部分代碼內容省略)。

route.js

const url = require('url');const path = require('path');const fs = require('fs');function getErrorInfo(errorType) {  // 省略代碼}function writeErrorPage(response, errorType) {  // 省略代碼}exports.register = function(request, response, mapping) {  // 解析請求路徑  var pathName = url.parse(request.url).pathname;  // 執行相應請求路徑的回呼函數  for(let i = 0, len = mapping.length;i < len;i++) {    if(mapping[i].url === pathName) {      mapping[i].handler(request, response);      return;    }  }  // 請求路徑為檔案返迴文件內容  var file = path.resolve(__dirname, '.' + pathName);  fs.exists(file, function(exists) {    // 請求路徑不存在返回404頁面    if(!exists) {      writeErrorPage(response, 'NOT_FOUND');    }    else {      var stat = fs.statSync(file);      // 請求路徑為目錄返回403頁面      if(stat.isDirectory()) {        writeErrorPage(response, 'FORBIDDEN');      }      else {        response.writeHeader(200, {          "Content-Type" : "text/html"        });        response.end(          fs.readFileSync(file, 'utf-8')        );      }    }  });}

將靜態資源請求的行為置後的設計,是為了保證回呼函數一定能執行。當靜態資源不存在時,應當返回不存在的錯誤,同時也設定了禁止目錄的訪問的規則。

後話

現在,只是實現了WEB伺服器基本的功能,它還有很大的改進空間。我將項目開源到github上,有興趣的可以複製下來。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.