node.js 08 代碼創建 http 靜態web服務器

之前已經介紹了 和 ,這為介紹本篇打下了基礎。

首先我們會介紹http靜態web服務器需要實現哪些需求,接下來我們會從node.js出發,介紹所需要的模塊。


node.js 08 代碼創建 http 靜態web服務器

http


http靜態web服務器

這裡的http靜態服務器是指創建靜態網站,並且通過node.js創建靜態web服務器來向客戶端提供服務。一個靜態web服務器的例子就是Apache,只需要把網站相關的html,css,javascript,jpg等靜態資源放到Apache的目錄下,只需要訪問主機名就可以顯示網頁了。

這裡面我們可以看到,靜態網站資源包括:

  • html文件
  • css文件
  • javascript文件

實際情況是,除了這三類主要文件,大部分網站資源還包括圖片文件,音頻文件,壓縮文件,字體文件等等。

而靜態網站的web服務器需要提供

  • http服務,可以對於客戶端提交的http請求,返回靜態頁面以及靜態頁面所需要使用的資源
    。假設需要訪問index.html頁面,那麼該頁面中使用到的圖片文件,css風格文件,javascript文件都需要返回給客戶端的瀏覽器用以展示。如果在程序中只返回了html文件,那麼瀏覽器將無法顯示關聯的圖片,響應的css效果,javascript效果也無法展示。
  • http端口,用於監聽客戶端提交的http請求,上面Apache使用的就是80端口。各個web服務器都支持端口的配置,那我們node.js也不例外,可以在程序中實現
  • 狀態碼:對於每一個客戶端請求,在返回頁面的同時,web服務器會返回一個狀態碼。請求處理成功的狀態碼是 200,而 404 則表示訪問的文件或者資源不存在。

HTTP Header 中的 Content-Type


node.js 08 代碼創建 http 靜態web服務器

http header

上圖是訪問某網站時的http response header。我們可以看到這次的 狀態碼 status code 是 200,表示請求處理成功。在返回的 response headers 裡面有一個Content-Type,這裡面的值是"text/html;charset=utf-8"。

  • text/html:表示返回頁面的格式是html,頁面在瀏覽器中以html的形式顯示。
  • charset: 返回頁面的字符集

有時候返回頁面的格式如果是"text/plain",表示頁面將以純本文的形式來展示。

這些格式統稱為 MIME (Multipurpose Internet Mail Extensions) 是描述消息內容類型的因特網標準。

根據不同文件類型,需要在http headers中的Content-Type裡面寫入對應的值。

具體可以在node.js中定義一個常量,通過鍵值對的方式根據文件後綴名來獲得Content-Type。

<code>const mimeType = {
'.ico': 'image/x-icon',
'.html': 'text/html',
'.js': 'text/javascript',
'.json': 'application/json',
'.css': 'text/css',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.wav': 'audio/wav',
'.mp3': 'audio/mpeg',

'.svg': 'image/svg+xml',
'.pdf': 'application/pdf',
'.zip': 'application/zip',
'.doc': 'application/msword',
'.eot': 'application/vnd.ms-fontobject',
'.ttf': 'application/x-font-ttf',
};/<code>

上面的代碼基本可以滿足一個靜態網站所需要的資源類型的定義。

代碼邏輯以及實現

  1. 通過node.js 創建http server,詳見
  2. 解析url
  3. 通過訪問路徑判斷文件或者目錄是否存在,如果不存在,則返回錯誤狀態碼 404
  4. 如果訪問路徑為目錄,則返回文件路徑index.html
  5. 根據請求路徑在response中寫入文件內容,同時根據資源類型設定Conten-type。

上面邏輯中所有跟文件處理,目錄處理相關的代碼都需要通過node.js中的fs模塊的調用來實現,詳見 。

具體代碼段如下:

<code>http.createServer(function (req, res) {
// 調用url模塊來解析訪問的url

const parsedUrl = url.parse(req.url);

// 提取路徑
const sPath = path.normalize(parsedUrl.pathname).replace(/^(\\.\\.[\\/\\\\])+/, '');
let pathname = path.join(__dirname, sPath);
//判斷路徑是否存在
fs.exists(pathname, function (exist) {
if(!exist) {
//如果路徑不存在,則返回404
res.statusCode = 404;
res.end(`File ${pathname} not found!`);
return;
}

// 如果路徑是目錄,則將路徑替換為目錄下的 index.html
if (fs.statSync(pathname).isDirectory()) {
pathname += '/index.html';
}

// 根據路徑讀取文件,此處調用fs模塊方法
fs.readFile(pathname, function(err, data){
if(err){
res.statusCode = 500;
res.end(`Error getting the file: ${err}.`);
} else {
// 獲取路徑後綴名
const ext = path.parse(pathname).ext;
// 根據後綴名獲取響應的content-type; 這裡的minType定義見上面的代碼塊
res.setHeader('Content-type', mimeType[ext] || 'text/plain' );
//通過end方法來結束response
res.end(data);
}
});
});
//提供http端口監聽
}).listen(8001);/<code>

這樣一個http靜態web服務器的代碼就完成了,非常輕便,跟很多語言比起來,可謂是很精悍了。

如果需要完整的代碼,煩請關注本號並留言。


分享到:


相關文章: