Node.js 是一個基於Chrome JavaScript 執行時建立的一個平臺。可以理解為是執行在服務端的 JavaScript。如果你是一個前端程式設計師,不太擅長像PHP、Python或Ruby等動態程式語言,想建立自己的服務,那麼Node.js是一個非常好的選擇。本文將通過幾個簡要步驟,運用express框架,搭建一個node服務。
一、安裝、搭建環境
1、新建一個資料夾,這裡暫時叫做“node-service”。
2、進入資料夾,cmd執行npm init,可根據自己需要填寫一些資訊,不需要定製的話,前面一路回車即可,只需要在最後,即下圖中紅色圈起部分輸入yes或者y。此時在資料夾內會生成一個package.json檔案。紅色劃線部分是我示例填寫,不是必需。
3、安裝express
命令:cnpm install express --save
此時資料夾中會生成node-modules資料夾,以上命令會將express框架安裝在node-modules目錄中。以下幾個重要模組,是可以與express一起安裝的,大家根據自己需要進行安裝即可。
body-parser - node.js 中介軟體,用於處理 JSON, Raw, Text 和 URL 編碼的資料。
cookie-parser - 一個解析Cookie的工具。通過req.cookies可以取到傳過來的cookie,並把它們轉成物件。
multer - node.js 中介軟體,用於處理 enctype="multipart/form-data"(設定表單的MIME編碼)的表單資料。
二、建立一個簡單例項
在我們建立 Node.js 第一個 "Hello, World!" 應用前,讓我們先了解下 Node.js 應用是由哪幾部分組成的:
引入 required 模組:我們可以使用 require 指令來載入 Node.js 模組。
建立伺服器:伺服器可以監聽客戶端的請求,類似於 Apache 、Nginx 等 HTTP 伺服器。
接收請求與響應請求 伺服器很容易建立,客戶端可以使用瀏覽器或終端傳送 HTTP 請求,伺服器接收請求後返回響應資料。
此時我們求建立一個服務:在客戶端發起請求時,響應"hello world"字串。
2.1、建立app.js檔案,示例程式碼如下:
var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('hello world'); }); let port = 8082; app.listen(port, () => { console.log(`Server listening on http://localhost::${port}, Ctrl+C to stop`) });
2.2、啟動服務:根目錄下執行命令 node app.js
2.3、在瀏覽器中訪問http://localhost:8082/ 或http://127.0.0.1:8082/,效果如下:
此時有文字輸出,說明服務搭建成功。
三、路由匹配
上文我們是在客戶端發起請求時,直接響應一段指定文字。但有時需要根據不同請求路徑或請求方式,返回不同資料。所以我們新建一個檔案app1.js,程式碼如下:
var express = require('express'); var app = express(); // 預設請求,輸出 "Hello World" app.get('/', function (req, res) { res.send('Hello GET'); }) // 使用者刪除介面 app.get('/user_del', function (req, res) { res.send('使用者刪除介面'); }) // 使用者資訊查詢介面 GET 請求 app.get('/user_list_query', function (req, res) { res.send('使用者列表資料'); }) let port = 8082; app.listen(port, () => { console.log(`Server listening on http://localhost::${port}, Ctrl+C to stop`) });
檔案中通過三個不同路徑暴露了三個介面,接下來我們可以訪問不同路徑,看驗證是否返回不同資訊。
可以看到,我們已經拿到了不同返回體。但也許有人會問,如果此時我有很多請求,難道都堆在app1.js裡嘛,能不能把請求歸類一下,讓app1.js整潔一些,只作為入口呢?當然可以。
假定現有兩類介面,每類各有三個介面 一、使用者管理 1、使用者列表查詢:user/user_list_query 2、使用者資訊刪除:user/user_del 3、使用者資訊修改:user/user_update 二、部門管理 1、部門列表查詢:dept/dept_list_query 2、部門刪除:dept/dept_del 3、部門修改:dept/dept_update
此時我們在app1.js同級建立api資料夾,資料夾下新建檔案user.js和dept.js。
// dept.js let express = require('express'); let router = express.Router(); // 部門修改介面 router.get('/dept_update', function (req, res) { res.send('部門修改介面'); }); // 部門刪除介面 router.get('/dept_del', function (req, res) { res.send('部門刪除介面'); }); // 部門資訊查詢介面 router.get('/dept_list_query', function (req, res) { res.send('部門列表資料'); }); module.exports = router;
user.js 與此類似,不再贅述。檔案中通過使用express.Router()註冊介面,通過module.exports丟擲整個模組,然後在app1.js中引入並使用該模組:
//app1.js var express = require('express'); var app = express(); let dept = require('./api/dept'); // 匹配請求,以dept開頭的對映到dept檔案中去 app.use('/dept', dept); let port = 8082; app.listen(port, () => { console.log(`Server listening on http://localhost::${port}, Ctrl+C to stop`) });
重新啟動8082服務。瀏覽器直接訪問http://localhost:8082/dept/dept_update,可以成功拿到返回體。
上面通過2種方式,實現了匹配介面路徑,給出不同返回體。做的更全一點,就可以模擬介面增刪改查邏輯了。提到邏輯處理,就會和請求引數掛鉤,所以我們向下看。
四、請求和響應處理
function中的req和res,分別是 request 和 response 物件。
request 物件 - 表示 HTTP 請求,包含了請求查詢字串,引數,內容,HTTP 頭部等屬性。
response 物件 - 表示 HTTP 響應,即在接收到請求時向客戶端傳送的 HTTP 響應資料。
這兩個物件的常見屬性簡單列舉如下,可根據自己需要進行呼叫。
req.app:當callback為外部檔案時,用req.app訪問express的例項 req.baseUrl:獲取路由當前安裝的URL路徑 req.body / req.cookies:獲得「請求主體」/ Cookies req.fresh / req.stale:判斷請求是否還「新鮮」 req.hostname / req.ip:獲取主機名和IP地址 req.originalUrl:獲取原始請求URL req.params:獲取路由的parameters req.path:獲取請求路徑 req.protocol:獲取協議型別 req.query:獲取URL的查詢引數串 req.route:獲取當前匹配的路由 req.subdomains:獲取子域名 req.accepts():檢查可接受的請求的文件型別 req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一個可接受字元編碼 req.get():獲取指定的HTTP請求頭
req.is():判斷請求頭Content-Type的MIME型別
res.app:同req.app一樣 res.append():追加指定HTTP頭 res.set()在res.append()後將重置之前設定的頭 res.cookie(name,value [,option]):設定Cookie opition: domain / expires / httpOnly / maxAge / path / secure / signed res.clearCookie():清除Cookie res.download():傳送指定路徑的檔案 res.get():返回指定的HTTP頭 res.json():傳送JSON響應 res.jsonp():傳送JSONP響應 res.location():只設定響應的Location HTTP頭,不設定狀態碼或者close response res.redirect():設定響應的Location HTTP頭,並且設定狀態碼302 res.render(view,[locals],callback):渲染一個view,同時向callback傳遞渲染後的字串,如果在渲染過程中有錯誤發生next(err)將會被自動呼叫。callback將會被傳入一個可能發生的錯誤以及渲染後的頁面,這樣就不會自動輸出了。 res.send():傳送HTTP響應 res.sendFile(path [,options] [,fn]):傳送指定路徑的檔案 -會自動根據檔案extension設定Content-Type res.set():設定HTTP頭,傳入object可以一次設定多個頭 res.status():設定HTTP狀態碼 res.type():設定Content-Type的MIME型別
五、靜態檔案伺服器
有時,我們的一些靜態檔案,例如圖片、CSS檔案、js檔案等,想放在一個伺服器上,此時node可以作為靜態檔案伺服器。
express 提供了內建的中介軟體 express.static 來設定靜態檔案路徑。
app.use('/public', express.static('public'));
我們在app.js同級,新建一個public目錄,存放靜態檔案。向裡面放一個css檔案和一張圖片。
5.1、按路徑讀取檔案:
新建app2.js檔案:
var express = require('express'); var app = express(); app.use('/public', express.static('public')); app.get('/', function(req, res){ res.send('hello world'); }); let port = 8082; app.listen(port, () => { console.log(`Server listening on http://localhost::${port}, Ctrl+C to stop`) });
將之前佔用8082埠的服務停掉,通過node app2.js 啟動服務。可以看到預設輸出"hello world"。此時我們嘗試輸入檔案路徑去讀靜態檔案。
5.2、介面返回靜態檔案
上面示例是需要自己輸入檔案路徑拿到檔案,有人說輸路徑太麻煩了,能不能通過一個介面返回指定靜態檔案呢?res.sendFile來了,新建app3.js :
var express = require('express'); var app = express(); app.use('/public', express.static('public')); app.get('/', function(req, res){ console.log(__dirname); // 列印結果:/node-service res.sendFile(__dirname+'/public/avatar.jpg'); }); let port = 8082; app.listen(port, () => { console.log(`Server listening on http://localhost::${port}, Ctrl+C to stop`) });
此時執行node app3.js 啟動服務,不用輸入檔案路徑,直接就可以看到圖片。
此時程式碼與5.1基本相同,差異是用了res.sendFile。
__dirname 是當前模組的目錄名。 相當於 __filename 的 path.dirname()。
console.log(__dirname); // 列印: /node-service console.log(path.dirname(__filename)); // 列印: /node-service,前提是引入了path模組,沒有引入的話,列印會報錯
Tips:
1、app.js檔案,每次改動都要重新啟動服務才能生效。
2、如果兩個js檔案用了同一個埠,同時啟動會報埠占用,可每次只起一個,或者用兩個埠。
3、啟動命令是node js 檔名,app.js只是示例
如果有需要,點選此處連結獲取文章例項原始碼(點我!點我!),或者關注公眾號可更早獲取文章~