HTTP 伺服器的基礎知識
var http=require('http');
http.createServer("/",function(req,res){
res.end("hello");
}).listen(3000);
console.log("start server")
複製程式碼
-
讀取請求頭及設定響應頭
- Node提供了幾個修改HTTP響應頭的方法: res.setHeader(field, value)res.getHeader(field) 和 res .removeHeader(field)
- 新增和移除響應頭的順序可以隨意,但一定要在呼叫 res.write() 或 res.end() 之前。在 響應主體的第一部分寫入之後,Node會重新整理已經設定好的HTTP頭。
-
設定HTTP響應的狀態碼
- 設定 res.statusCode 屬性。在程式響應期間可以隨時給這個屬性賦值,只要是在第一次呼叫 res.write() 或 res.end() 之前就行。
構建 RESTful Web 服務
用POST請求建立資源
var http = require('http');
var url = require('url');
var items = [];
var server = http.createServer(function(req, res){
switch (req.method) {
case 'POST':
var item = '';
req.setEncoding('utf8');
req.on('data', function(chunk){
item += chunk;
});
req.on('end', function(){
items.push(item);
res.end('OK\n');
});
break;
}
});
複製程式碼
預設情況下, data 事件會提供 Buffer 物件,這是Node版的位元組陣列。而對於文字格式的待 辦事項而言,你並不需要二進位制資料,所以最好將流編碼設定為 ascii 或 utf8 ;這樣 data 事件 會給出字串。這可以通過呼叫 req.setEncoding(encoding) 方法設定。
提供靜態檔案服務
- 建立一個靜態檔案伺服器
最基本的ReadStream靜態檔案伺服器
var http = require('http');
var parse = require('url').parse;
var join = require('path').join;
var fs = require('fs');
var root = __dirname;
var server = http.createServer(function(req, res){
var url = parse(req.url);
var path = join(root, url.pathname);
var stream = fs.createReadStream(path);
stream.on('data', function(chunk){
res.write(chunk);
});
stream.on('end', function(){
res.end();
});
});
server.listen(3000);
複製程式碼
- __dirname 在Node中是一個神奇的變數,它的值是該檔案所在目錄的路徑。 __dirname 的 神奇之處就在於,它在同一個程式中可以有不同的值,如果你有分散在不同目錄中的檔案的話。
- 用 STREAM.PIPE() 優化資料傳輸
- 處理伺服器錯誤
- 我們的靜態檔案伺服器還沒有處理因使用 fs.ReadStream 可能出現的錯誤。如果你訪問不 存在的檔案,或者不允許訪問的檔案,或者碰到任何與檔案I/O有關的問題,當前的伺服器會拋 出錯誤。
- 在Node中,所有繼承了 EventEmitter 的類都可能會發出 error 事件。像 fs.ReadStream 這樣的流只是專用的 EventEmitter ,有預先定義的 data 和 end 等事件,我們已經看過了。預設 情況下,如果沒有設定監聽器, error 事件會被丟擲。也就是說如果你不監聽這些錯誤,那它們 就會搞垮你的伺服器。
- 為了防止伺服器被錯誤搞垮,我們要監聽錯誤,在 fs.ReadStream 上註冊一個 error 事件 處理器(比如下面這段程式碼),返回響應狀態碼500表明有伺服器內部錯誤:
用 fs.stat() 實現先發制人的錯誤處理
fs.stat() 用於得到檔案的相關資訊,比如它的大小,或者得到錯誤碼。如果檔案不存在, fs.stat() 會在 err.code 中放入 ENOENT作為響應,然後你可以返回錯誤碼404,向客戶端表明檔案未找到。如果 fs.stat() 返回了其他 錯誤碼,你可以返回通用的錯誤碼500。
var server = http.createServer(function(req, res){
var url = parse(req.url);
var path = join(root, url.pathname);
fs.stat(path, function(err, stat){
if (err) {
if ('ENOENT' == err.code) {
res.statusCode = 404;
res.end('Not Found');
} else {
res.statusCode = 500;
res.end('Internal Server Error');
}
} else {
res.setHeader('Content-Length', stat.size);
var stream = fs.createReadStream(path);
stream.pipe(res);
stream.on('error', function(err){
res.statusCode = 500;
res.end('Internal Server Error');
});
}
});
});
複製程式碼
從表單中接受使用者輸入
處理提交的表單域
表單提交請求帶的 Content-Type 值通常有兩種:
- application/x-www-form-urlencoded :這是HTML表單的預設值;
- multipart/form-data :在表單中含有檔案或非ASCII或二進位制資料時使用。
- 支援GET和POST的HTTP伺服器
var http = require('http');
var items = [];
var server = http.createServer(function(req, res){
if ('/' == req.url) {
switch (req.method) {
case 'GET':
show(res);
break;
case 'POST':
add(req, res);
break;
default:
badRequest(res);
}
} else {
notFound(res);
}
});
server.listen(3000);
複製程式碼
- 待辦事項列表頁面的表單和事項列表
- QUERYSTRING模組
用formidable處理上傳的檔案
參考《Node.js in Action》的4.4.2
計算上傳進度
Formidable的 progress 事件能給出收到的位元組數,以及期望收到的位元組數。我們可以藉助 這個做出一個進度條。
用 HTTPS 加強程式的安全性
HTTPS伺服器配置項
例子中所用的證書不是由證書頒發機構頒發的,所以會 顯示一個警告資訊。這裡可以忽略這個警告,但如果要把網站部署到公網上,你就應該找個證書 頒發機構(CA)進行註冊,併為你的伺服器取得一份真實的、受信的證書。