node開發web程式---04構建node web程式

youngeffort發表於2019-01-10

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) 方法設定。

提供靜態檔案服務

  1. 建立一個靜態檔案伺服器

最基本的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() 優化資料傳輸

node開發web程式---04構建node web程式

  1. 處理伺服器錯誤
  • 我們的靜態檔案伺服器還沒有處理因使用 fs.ReadStream 可能出現的錯誤。如果你訪問不 存在的檔案,或者不允許訪問的檔案,或者碰到任何與檔案I/O有關的問題,當前的伺服器會拋 出錯誤。
  • 在Node中,所有繼承了 EventEmitter 的類都可能會發出 error 事件。像 fs.ReadStream 這樣的流只是專用的 EventEmitter ,有預先定義的 data 和 end 等事件,我們已經看過了。預設 情況下,如果沒有設定監聽器, error 事件會被丟擲。也就是說如果你不監聽這些錯誤,那它們 就會搞垮你的伺服器。
  • 為了防止伺服器被錯誤搞垮,我們要監聽錯誤,在 fs.ReadStream 上註冊一個 error 事件 處理器(比如下面這段程式碼),返回響應狀態碼500表明有伺服器內部錯誤:

node開發web程式---04構建node web程式

用 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 值通常有兩種:

  1. application/x-www-form-urlencoded :這是HTML表單的預設值;
  2. 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);
複製程式碼
  • 待辦事項列表頁面的表單和事項列表

node開發web程式---04構建node web程式

  • QUERYSTRING模組

node開發web程式---04構建node web程式

用formidable處理上傳的檔案

參考《Node.js in Action》的4.4.2

計算上傳進度

Formidable的 progress 事件能給出收到的位元組數,以及期望收到的位元組數。我們可以藉助 這個做出一個進度條。

node開發web程式---04構建node web程式

用 HTTPS 加強程式的安全性

HTTPS伺服器配置項

node開發web程式---04構建node web程式
例子中所用的證書不是由證書頒發機構頒發的,所以會 顯示一個警告資訊。這裡可以忽略這個警告,但如果要把網站部署到公網上,你就應該找個證書 頒發機構(CA)進行註冊,併為你的伺服器取得一份真實的、受信的證書。

相關文章