在用 Node.js 實作一個 Apache HTTP Server (一)中,已經初步用 Node.js 做出 Apache server 的功能了,我們可以透過 url 訪問伺服器 www 資料夾內的對應資源。接著我們要來實現另一項功能:

圖片來源: 
  
    網路
  
在 Apache 中,如果請求地址對應的資源是一個資料夾,Apache 會回應一個網頁,並將該資料夾內部的檔案顯示在網頁中。 
目前程式碼
| 1 | // server.js | 
判斷請求路徑是否為資料夾
當請求路徑為資料夾時,顯示目錄頁面
目前我們可以造訪 ./www 資料夾內的檔案,但如果是請求路徑對應到的資源是資料夾的話,伺服器目前會回傳 404。現在我們需要做兩件事情:
- 當收到客戶端請求時,先確認該請求路徑在 ./www資料夾中,是否有對應資源
- 若確認有對應資源,判斷該請求路徑對應的目標是資料夾或是檔案,若是資料夾就渲染目錄頁面,若是檔案就直接回應該檔案
fs.access() 判斷路徑是否存在
| 1 | server.on('request', function (req, res) { | 
fs.statSync() 取得資源的實例(Stats)
將檔案路徑帶入參數
| 1 | fs.statSync(fullPath) | 
返回一個物件
| 1 | Stats { | 
isDirectory() 判斷是否為資料夾
我們可以透過 fs.statSync(fullPath).isDirectory() 來判斷該請求路徑是否為資料夾,該 API 會回傳一個布林值
| 1 | fs.access(fullPath, function (err) { | 
接著就可以專心處理請求路徑是資料夾時要做的後續邏輯了
抓取資料夾內檔案/資料夾的名稱
現在我們已經可以判斷請求路徑是不是資料夾了,接著我們需要:
- 透過 Node.js 抓取目前請求路徑資料夾內的所有成員(包含資料夾及檔案)的名稱,丟到畫面上讓使用者看
fs.readdir() 取資料夾內的成員
fs.readdir() 接收兩個參數
- 資料夾路徑字串
- callback function,此函式有兩個參數- 第一個參數是 error- 讀取成功時為 null
- 讀取失敗時為一個物件
 
- 讀取成功時為 
- 第二個參數是 data- 讀取成功時為一個陣列,包含該資料夾內所有成員檔名字串 ex. [‘index.html’, ‘main.css’, ‘a-dir’]
- 讀取失敗時為 undefined
 
 
- 第一個參數是 
| 1 | if (fs.statSync(fullPath).isDirectory()) { | 
模板引擎 art-template
基本的 art-template 用法請參考在 Node.js 中使用 art-template 模板引擎
延續上面的程式碼,接著我們要使用模板引擎將取得的資料夾成員處理成目錄頁面回傳給客戶端
| 1 | if (fs.statSync(fullPath).isDirectory()) { | 
目錄頁面模板 (template.html)
| 1 | <body> | 
這邊的 HTML 省略了 CSS 樣式,需要完整版請參考目錄頁面模板
Demo
現在我在專案目錄下的 www 開放資源資料夾新增些檔案,接著來訪問看看這些資源,看看效果吧。

還有一些可以優化的部分,下一篇再讓我們繼續吧:
- 取得檔案大小、創建時間、修改時間資訊,判斷檔案類型 icon
- 點擊目錄內的檔案名,可以直接造訪該檔案
- 大標題路徑與請求路徑一致
- 當造訪的目錄內有 index為名的檔案時,不顯示目錄,而是該檔案
- 優化程式碼