1. 程式人生 > >第四十六篇:MAC下使用 Node.js 實現一個 WebServer 伺服器

第四十六篇:MAC下使用 Node.js 實現一個 WebServer 伺服器

引序:

  • Node.js 採用一系列“非阻塞”庫來支援事件迴圈的方式。Node.js是一個伺服器端 JavaScript 直譯器 , 也就是說 Node.js 是一個支援 JavaScript 語法編寫伺服器程式碼的環境。

在MAC下用命令安裝 Node.js

安裝 Homebrew

安裝 Node 環境

brew install node

檢視 Node 版本號,判斷是否安裝成功

node -v

  • 注意:當最後一步檢視到版號時,表示已經安裝成功。那麼這個時候即可以使用 node 的操作命令,也可以使用 npm 的操作命令

node 和 npm 操作命令的使用

建立伺服器時的初始化, cd 到指定的目錄下

npm init

  • 注意:之後會停在一個 package name:(…) 輸入包名 ;接下來只需要按 回車鍵 直到提示 Is this ok? (yes) 輸入yes ;即可完成初始化

下載引入 express 框架,即可開始使用 Visual Studio Code 軟體進行服務端編碼

npm install express -save

當編碼完伺服器程式碼後,使用下面的命令就可以開起我們編寫的伺服器程式碼

node 檔名.js

  • 注意:在建立的每個檔名後面新增字尾 .js ,這樣可以使得在寫程式碼時有提示

實現 WebServer 伺服器的一些語法使用

實現基於 http 框架模組的伺服器

  • 引入 http 框架模組

    // 與 OC 的 import 一樣 , 用 http 變數去拿該檔案內部的東西

    var http = require(‘http’);

  • 建立 webserver

// 預設是 GET 請求
var server =  http.createServer(function(request,response){
    // 只要訪問伺服器就會執行
    console.log('請求伺服器');

    // 響應伺服器請求,返回資料 "holle world"
// response.write('holle world'); // response.end(); response.end('holle world',function(request,response){ console.log('伺服器完成響應,結束啦'); }); });
  • 監聽 8080 埠號

    // 監聽埠訪問
    server.listen(3000,'192.168.31.200');

  • 客戶端訪問服務端

/ 請求 manager.requestSerializer =
    // AFHTTPRequestSerializer : 請求的引數內所有的值 沒有 陣列 或 字典 使用這個
    // AFJSONRequestSerializer : 請求的引數內所有的值   有 陣列 或 字典 使用這個

    // 響應 manager.responseSerializer =
    // AFHTTPResponseSerializer : 返回的引數內所有的值 沒有 陣列 或 字典 使用這個
    // AFJSONResponseSerializer : 返回的引數內所有的值   有 陣列 或 字典 使用這個


    AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];

    // 請求傳的引數中的值沒有 陣列 或 字典 ,所以使用 AFHTTPRequestSerializer
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];

    // 響應 
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 只有響應有這個型別的設定 , 可以解析返回引數內有 json 資料,原因如下
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];


    // GET 請求 , 192.168.31.200 為服務端網路地址
    [manager GET:@"http://192.168.31.200:8080" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

        NSString * resultText = [[NSString alloc] initWithData:responseObject encoding:kCFStringEncodingUTF8];

        NSLog(@"%@",resultText);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        NSLog(@"%@",error);

    }];


    // POST 請求 , /qujie/post/www/require 為路由地址
   // [manager POST:@"http://192.168.31.200:9090/qujie/post/www/require" parameters:@{@"name":@"qujie",@"age":@(24),@"phone":@"19665568780"} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

      //  NSString * resultText = [[NSString alloc] initWithData:responseObject encoding:kCFStringEncodingUTF8];

     //   NSLog(@"%@\n",resultText);

   // } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

     //   NSLog(@"%@",error);

 // }];
  • 注意:首先編寫完伺服器程式碼後應該啟動伺服器, 在客戶端 GET 請求成功後,會返回 holle world 給客戶端。測式介面也可以用瀏覽器,在瀏覽器中直接輸入地址:http://192.168.31.200:8080 就能看到資料,這就算是一個簡單完整的 webserver 伺服器

express 模組框架搭建 webServer

// express:搭建 webServer

// 1.引入 express 模組
var express = require('express');

// 2.建立伺服器
var webServer = express();

// 2.1 處理 get 請求
webServer.get('/qujie/web/server/get/require',function(require,response){
    console.log('收到 get 請求');

    // 傳送給客戶端資料
    response.send('get 瞿傑 說2017年8月30號的天氣很好,也很熱');
});

webServer.post('/qujie/web/server/post/require',function(require,response){
    console.log('收到 post 請求');

    // 傳送給客戶端資料
    response.send('post 瞿傑 說2017年8月30號的天氣很好,也很熱');
});

// 3.監聽,輸入埠號,第二個引數本服務端地址 可以省去
webServer.listen('8080');

console.log('監聽8080商品 get 請求');

express 路由地址 “/qujie/get/luyou/require”

var express = require('express');

var server = express();


// 1.簡單的路由功能,就是新增請求地址
server.get('/qujie/get/luyou/require',function(require,response){

    // get 請求
    console.log('客戶端 get 請求 服務端');

    response.send('express 路由 get 請求');
});


// 2.或是使用路由控制代碼,對照上面的程式碼不同之處
// 特點:第一個函式多了一個 next 引數,緊接著多了一個函式b 用來發送資料給客戶端的
server.get('/qujie/get/luyou/jubing/require',function(require,response,next){
    // get 請求
    console.log('客戶端 get 請求 服務端');

    // 從資料庫查詢 獲取資料,然後把資料傳送給客戶端
    next();

} , function sendMessage(require,response){

    response.send('express luyou jubing 路由 get 請求');

});


server.listen('8080');

console.log('03-express路由監聽');
  • 呼叫該 next() 會跳到 sendMessage() 函式

中介軟體 use(…)

  • 在使用中介軟體時,請求會路由到第一個中介軟體程式碼塊,然後執行程式碼,next() 函式就是為了 跳轉到下一塊的中介軟體程式碼塊
// 引入 express 框架
var express = require('express');

// 拿到伺服器
var server = express();

// 變數
var dataMg ;

// 1.查詢資料程式碼塊,使用中介軟體 把程式碼分開,可以看的很清楚
server.use('/qujie/get/require',function(require,response,next){
    console.log('執行第一塊程式碼,查詢資料');

    dataMg = 'get 這裡查詢結果,傳送給客戶端' ;

    next();
});
// 2.傳送資料程式碼塊
server.get('/qujie/get/require',function(require,response){

    console.log('傳送資料');

    response.send(dataMg);
});


// POST 請求
server.use('/qujie/post/require',function(require,response,next){
    console.log('執行第一塊程式碼,查詢資料');

    dataMg = 'post 這裡查詢結果,傳送給客戶端' ;

    next();
});
server.post('/qujie/post/require',function(require,response){

        console.log('傳送資料');

        response.send(dataMg);
    });

// 監聽
server.listen('8080');

console.log('監聽 8080/ qujie/get/require 埠請求 ');

解析客戶端 Get 請求傳的引數

  • require.query : 客戶端向服務端請求的引數 , 取裡面的值可以直接用點語法
// http://192.168.31.200:9090/qujie/get/require?name=qujie&age=24&phoneNum=186666777

var express = require('express');

var server = express();

server.get('/qujie/get/require',function(require,response){

    // require.query 是請求的引數,可以查詢
    console.log(require.query.name,require.query.age,require.query.phoneNum);

    response.send(require.query);
});

server.listen('9090');

console.log('開始監聽 9090 埠請求');

解析客戶端 Post 請求傳的引數

  • 注意:
    • 引入 body-parser 框架模組,就需要使用命令 npm install body-parser – save 下載程式碼
// 1.引入 express 框架
var express = require('express');


// 2.引入 body-perser 框架 用來解析 POST 請求資料
var bodyParser = require('body-parser');

// 3直接把 POST 請求體的資料解析出來,存入 require.body
// 3.1解析 www 格式( application/x-www-form-urlencoded ) POST 引數解析器, 是一個 function
var urlencodedParser = bodyParser.urlencoded({extended:true});

// 3.2解析 json 格式( application/json ) POST 引數解析器 , 是一個 function
var jsonParser = bodyParser.json();


// 4.建立伺服器
var server = express();


// 5.使用中介軟體 use 解析資料
// 5.1 '/qujie/post/www/require' 路由的 POST 請求,解析請求引數
server.use('/qujie/post/www/require',urlencodedParser);

// 5.2 '/qujie/post/json/require' 路由的 POST 請求,解析請求引數
server.use('/qujie/post/json/require',jsonParser);


// 6.POST請求
// 6.1 '/qujie/post/www/require' 的 POST 請求
server.post('/qujie/post/www/require',function(require,response){

    console.log(require.body);

    response.send({'other':'qujie www POST 請求後返回的值' , 'body':require.body});
});

// 6.2 '/qujie/post/json/require' 的 POST 請求
server.post('/qujie/post/json/require',function(require,response){

        console.log(require.body);

        response.send({'other':'qujie json POST 請求後返回的值' , 'body':require.body});
});


// 7.監聽
server.listen('9090');

console.log('開始監聽 9090 埠 POST 請求');

js 語法中的 陣列、字典建立與使用

  • 注意:建立函式時 函式名稱必須是小寫字母開頭,如果是大寫的話就會被認為是一個類

// 字典 {}
function dictionaryDome(){

    var dict = {'name':'qujie','age':18,'lala':'haha'};

    // 向字典中新增鍵值對
    dict.money = 8888888;

    dict['aaaa'] = 'aaaa';

    console.log(dict);

    // 刪除字典中的鍵值
    delete dict['lala'] ;

    delete dict.age ;

    console.log(dict);
};

dictionaryDome();



// 陣列 [] 
function arrayDome(){

    // 1.陣列的下標都是從 0 開始的
    var array = ['qujie','19',188];

    // 2.向 陣列中 新增元素
    array.push('aaaa');   

    // 2.1 新增元素 
    //     1:開始插入下標為 1 的位置
    //     0:從開始插入的位置後面連續 0 個 被刪除
    //     '元素值':需要插入到陣列中的 值
    array.splice(1,0,'元素值')

    console.log(array);

    // 3.刪除最後一個元素,陣列等同於棧
    array.pop();

    console.log(array);

    // // 3.1 delete 刪除 , 這個功能是 只刪除了值,位置卻還在 ,不行
    // delete array[2];

    // 3.2 splice 刪除 , 功能是 可以刪除一連串的元素
    //     第一個數字 2 表示刪除元素下標的開始
    //     第二個數字 3 表示連續刪除元素的個數
    array.splice(2,3);

    console.log(array);

    // underscore: js 操作
    var underscore = require('underscore');

    // 判斷是否包含指定的值 , 根據地址判斷
    // array : 陣列
    // 'qujie': 指定的值
    // 2     : 指定從陣列下標為 2 開始向後判斷是否包含元素
    var isContain = underscore.contains(array,'qujie',2);
    console.log(isContain);
};

arrayDome();



var express = require('express');

var server = express();

// 返回資料
var dic = {'name':'qujie','age':18};

server.get('/',function(require,response){
    response.send(dic);
});

server.listen(8080);

console.log('開始監聽 8080 埠');

自定義類 與使用

  • 引入 underscore 框架模組 可以用來做判斷
// 函式 與 自定義類 區別:函式首字母小寫 ,而類名首字母大寫

// 函式
function user(){

} ;


// 自定義類
// name , age 是類的屬性
function User(name,age){
    this.name = name ;
    this.age = age ;

    // 定義類的函式
    this.describe = function (){
        console.log('當前的人名為:',this.name ,'年齡為:',this.age);
    };
};


// 建立物件時必須使用 new 
var user = new User('qujie',18);

// 打印出 user 物件的屬性 和 方法
console.log(user);

// 呼叫 user 的 describe 方法
user.describe();



var user2 = new User('qujie',18);
// 引入 underscore 框架模組
var underscore = require('underscore');

// underscore.isEqual(user,user2) 是根據地址判斷的,並非值的判斷
// var isEque = underscore.isEqual(user,user2);

// underscore.contains([user],user2) 也是根據地址判斷,並非值的判斷
var isEque = underscore.contains([user],user2);

console.log(isEque);

模組開發

  • ./ :表示當前檔案目錄下
  • Tools.js 檔案在 “./Until模組開發” 目錄下
// 將一些基本變數暴露到外面,使可以在外面使用

var age = 18 ;
var name = 'qujie';

exports.age = age ;
exports.name = name ;


function describe(){

    console.log('name:',name , 'age:',age);
}

exports.describe = describe ;
  • User.js 檔案在 “./User模組開發” 目錄下
// 自定義類暴露到外面,供外面使用

function User(name,age){
    this.name = name ;
    this.age = age ;

    this.describe = function(){
        console.log('name:',this.name,'age:',this.age);
    }
}

// 匯出
module.exports = User ;


// 注意:這樣的使用是 不正確的
// exports.User = User ;


// 注意:如果當前檔案使用了 module 就不能用 exports 匯入,不然無法使用 console.log(User.phoneNum);
// var phoneNum = 18665568889 ;
// exports.phoneNum = phoneNum ;
  • 在外面的檔案 express模組開發.js 中使用 User.js 和 Tools.js 中內容
// 匯入自定義的工具模組
var tool = require('./Until模組開發/Tools');

// 可以直接這樣取
// tool.age = 18;
// tool.name ;
tool.describe();


// 匯入自定義類
var User = require('./User模組開發/User');
var user = new User('qujie',20);
// 使用類的物件方法
user.describe();


// 匯入 express 框架
var express = require('express');

var server = express();

server.get('/',function(require,response){

    // 自動把 tool 暴露在外面的變數轉成Json字典
    // response.send(tool);

    // 自動把 user 物件的屬性轉成Json字典
    response.send(user);
});

server.listen('8080');

console.log('開始監聽模組開發 8080 埠');