4. 構(gòu)建Node Web程序
1.HTTP服務(wù)器的基本知識
呈現(xiàn)一個HTTP請求
var http = require("http");
var server = http.createServer(function(req, res) {
// 讀取請求頭 以及 設(shè)置響應(yīng)頭
var body = "cool!";
res.setHeader("Content-Length", body.length);
res.setHeader("Content-Type", "text/plain");
// 設(shè)置狀態(tài)碼
res.statusCode = 302;
// 處理請求
// res.write(body)
// res.end();
res.end(body);
});
server.listen(3000);
- 添加和移除響應(yīng)頭的順序可以隨意皆怕,但一定要在調(diào)用res.write()或 res.end()之前毅舆。
- 在響應(yīng)主體的第一部分寫入之后,Node會刷新已經(jīng)設(shè)定好的HTTP頭愈腾。
2. 構(gòu)建RESTful Web服務(wù)
1. 用POST請求創(chuàng)建資源
var http = require("http");
var server = http.createServer(function(req, res) {
// 設(shè)置utf8后, 下面data就會給出字符串,而不是對象
req.setEncoding('utf8')
// 讀取請求頭 以及 設(shè)置響應(yīng)頭
req.on("data", function(chunk) {
console.log("parsed" + chunk);
});
req.on("end", function() {
console.log("done parsing");
res.end();
});
});
server.listen(3000);
5. 存儲Node程序中的數(shù)據(jù)
1. 無服務(wù)的數(shù)據(jù)存儲
- 內(nèi)存存儲
- 弊端: 不能持久化
- 基于文件的存儲
- 弊端: 單文件并發(fā)有問題.
2. 關(guān)系型數(shù)據(jù)庫管理系統(tǒng)
關(guān)系型數(shù)據(jù)庫,查詢起來很容易, 開源軟件也可以不花錢
- MySQL
- node-mysql 模塊(https://github.com/felixge/node-mysql)
npm install mysql
- PostgreSQL
- 輕量目錄訪問協(xié)議
- 通過安全服務(wù)應(yīng)用程序接口
- 同步復制: 在每次數(shù)據(jù)操作后對復制進行驗證,從而防止數(shù)據(jù)丟失
npm install pg
3. NoSQL數(shù)據(jù)庫
含義是 No SQL
或者 Not only SQL
- Redis
- 適合處理不需要長期訪問的數(shù)據(jù)存儲
- 數(shù)據(jù)存儲于 RAM 中
- 數(shù)據(jù)存儲有限, 但數(shù)據(jù)操作非潮锘睿快
npm install redis
- MongoDB
- 通用的 非關(guān)系型 數(shù)據(jù)庫,
npm install mongodb
- Mongoose
- 其可以順暢地使用MongoDB
- 提供了一些實用的功能
6. Connect
其是一個框架, 使用中間件的模塊化組件.
1. 搭建一個Connect程序
- 第三方模塊需要安裝.
npm install connect
var connect = require('connect');
var app = connect();
app.listen(3000);
2. 工作機制
- 其中間件概念受到Ruby的Rack框架的啟發(fā).
- 小巧
- 自包含
- 可以在整個程序中重用
-
next()
在中間件里調(diào)用, 用回調(diào)函數(shù),而不是從方法中返回, 是為了可以在中間件組件里運行異步邏輯.
var connect = require("connect");
function logger(req, res, next) {
console.log("%s %s", req.method, req.url);
next();
}
function hello(req, res) {
res.setHeader("Content-Type", "text/plain");
res.end("hello world!");
}
connect()
.use(logger)
.use(hello)
.listen(3000);
3. 中間件的順序很重要
如果前一個中間件,不調(diào)用next(), 命令鏈中的后續(xù)中間件都不會被調(diào)用.
4. 掛載中間件和服務(wù)器
可以根據(jù)掛載的路徑前綴.選擇性的調(diào)用中間件
var connect = require("connect");
connect()
.use(logger)
.use('/admin',restrice)
.use('/admin',admin)
.use(hello)
.listen(3000);
function admin(req, res, next) {
switch (req.url) {
case "/":
res.end("try /users");
break;
case "/users":
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify(["tobi", "loki", "jane"]));
break;
}
}
5. 創(chuàng)建可配置中間件
利用閉包, 返回可以配置的中間件
function setup(options) {
// 設(shè)置邏輯
return function (req, res, next) {
// 中間件邏輯
}
}
app.use(setup({some:'options'}))