欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Node.js實戰(zhàn) 建立簡單的Web服務(wù)器

 更新時間:2012年03月08日 22:13:04   作者:  
本章我們同樣通過實戰(zhàn)的演練,利用Node.js建立一個簡單的Web服務(wù)器
前面一章,我們介紹了Node.js這個面向互聯(lián)網(wǎng)服務(wù)的JavaScript服務(wù)器平臺,同時Node.js的運(yùn)行環(huán)境已經(jīng)搭建起來,并通過兩段HelloWorld程序驗證了Node.js的基本功能。本章我們同樣通過實戰(zhàn)的演練,利用Node.js建立一個簡單的Web服務(wù)器。

    如果你熟悉.NET或其他類似平臺的Web開發(fā),你可能會像,建立一個Web服務(wù)器有什么,在Visual Studio中建立一個Web工程,點(diǎn)擊運(yùn)行即可。事實的確是這樣,但請不要忘記,這樣的代價是,比如果說,你是用.NET開發(fā)Web應(yīng)用,你就使用了完整的IIS作為你的Web服務(wù)器基礎(chǔ),這樣當(dāng)你的應(yīng)用發(fā)布時就只能用IIS了。而如果使用獨(dú)立服務(wù)器(利用System.Web.Hosting自己構(gòu)建的話),你則必須處理各種HttpListener和相應(yīng)線程,則會比較麻煩,畢竟.NET不是專注于面向Web的。Node.js在這方面提供了方便且可定制的途徑,你可以在其基礎(chǔ)上構(gòu)建精巧且完全面向你應(yīng)用的服務(wù)平臺。


一、建立簡單的Web服務(wù)器涉及到Node.js的一些基本知識點(diǎn):

1、請求模塊
在Node.js中,系統(tǒng)提供了許多有用的模塊(當(dāng)然你也可以用JavaScript編寫自己的模塊,以后的章節(jié)我們將詳細(xì)講解),如http、url等。模塊封裝特定的功能,提供相應(yīng)的方法或?qū)傩裕褂眠@些模塊,需要先請求模塊獲得其操作對象。

例如要使用系統(tǒng)的http模塊,可以這樣寫:

復(fù)制代碼 代碼如下:

var libHttp = require('http'); //請求HTTP協(xié)議模塊

這樣,以后的程序?qū)⒖梢酝ㄟ^變量libHttp訪問http模塊的功能。本章例程中使用了以下系統(tǒng)模塊:
http:封裝http協(xié)議的服務(wù)器和客戶端實現(xiàn);
url:封裝對url的解析和處理;
fs:封裝對文件系統(tǒng)操作的功能;
path:封裝對路徑的解析功能。
有了這些模塊,我們就可以站在巨人的肩膀上構(gòu)建自己的應(yīng)用。
2、控制臺
為了更好的觀察程序的運(yùn)行,方便在異常時查看錯誤,可以通便變量console使用控制臺的功能。
復(fù)制代碼 代碼如下:

console.log('這是一段日志信息');
計時并在控制臺上輸出計時信息:
//開始計時
console.timeEnd('計時器1'); //開始名稱為“計時器1”的計時器
...
...
...
//結(jié)束計時,并輸出到控制臺
console.timeEnd('計時器1'); //結(jié)束稱為“計時器1”的計時器并輸出

3、定義函數(shù)
在Node.js中定義函數(shù)的辦法與普通JavaScript中完全相同,不過我們推薦的寫法如下,即使用一個變量為函數(shù)命名,這樣可以比較方便明確的將函數(shù)作為參數(shù)傳遞給其他函數(shù):
復(fù)制代碼 代碼如下:

//定義一個名為showErr的函數(shù)
var showErr=function(msg){
var inf="錯誤!"+msg;
console.log(inf+msg);
return msg;
}

4、創(chuàng)建Web服務(wù)器并偵聽訪問請求
創(chuàng)建Web服務(wù)器最重要的是提供Web請求的響應(yīng)函數(shù),它有兩個參數(shù),第一個代表客戶端請求的信息,另一個代表將要返回給客戶端的信息。在響應(yīng)函數(shù)中應(yīng)解析請求信息,依據(jù)請求,組裝返后內(nèi)容。
復(fù)制代碼 代碼如下:

//請求模塊
var libHttp = require('http'); //HTTP協(xié)議模塊
//Web服務(wù)器主函數(shù),解析請求,返回Web內(nèi)容
var funWebSvr = function (req, res){
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html><body>');
res.write('<h1>*** Node.js ***</h1>');
res.write('<h2>Hello!</h2>');
res.end('</body></html>');
}
//創(chuàng)建一個http服務(wù)器
var webSvr=libHttp.createServer(funWebSvr);
//開始偵聽8124端口
webSvr.listen(8124);

5、解析Web請求
對于簡單的Web網(wǎng)頁訪問請求,重要的信息包含在請求信息參數(shù)的url里,我們可以使用url解析模塊解析url中的訪問路徑,并利用path模塊,將訪問路徑組裝為要訪問的實際文件路徑用于返回。
復(fù)制代碼 代碼如下:

var reqUrl=req.url; //獲取請求的url
//向控制臺輸出請求的路徑
console.log(reqUrl);
//使用url解析模塊獲取url中的路徑名
var pathName = libUrl.parse(reqUrl).pathname;
//使用path模塊獲取路徑名中的擴(kuò)展名
if (libPath.extname(pathName)=="") {
//如果路徑?jīng)]有擴(kuò)展名
pathName+="/"; //指定訪問目錄
}
if (pathName.charAt(pathName.length-1)=="/"){
//如果訪問目錄
pathName+="index.html"; //指定為默認(rèn)網(wǎng)頁
}
//使用路徑解析模塊,組裝實際文件路徑
var filePath = libPath.join("./WebRoot",pathName);

6、設(shè)置返回頭
由于是Web請求,需要在返回內(nèi)容中包含http返回頭,這里重點(diǎn)是依據(jù)要訪問的文件路徑的文件擴(kuò)展名,設(shè)置http返回頭的內(nèi)容類型。
復(fù)制代碼 代碼如下:

var contentType="";
//使用路徑解析模塊獲取文件擴(kuò)展名
var ext=libPath.extname(filePath);
switch(ext){
case ".html":
contentType= "text/html";
break;
case ".js":
contentType="text/javascript";
break;
...
...
default:
contentType="application/octet-stream";
}
//在返回頭中寫入內(nèi)容類型
res.writeHead(200, {"Content-Type": contentType });

7、向返回對象中寫入訪問的文件內(nèi)容
有了需要訪問的文件實際路徑,有了文件對應(yīng)的內(nèi)容類型,就可以利用fs文件系統(tǒng)模塊讀取文件流并返回給客戶端。
復(fù)制代碼 代碼如下:

//判斷文件是否存在
libPath.exists(filePath,function(exists){
if(exists){//文件存在
//在返回頭中寫入內(nèi)容類型
res.writeHead(200, {"Content-Type": funGetContentType(filePath) });
//創(chuàng)建只讀流用于返回
var stream = libFs.createReadStream(filePath, {flags : "r", encoding : null});
//指定如果流讀取錯誤,返回404錯誤
stream.on("error", function() {
res.writeHead(404);
res.end("<h1>404 Read Error</h1>");
});
//連接文件流和http返回流的管道,用于返回實際Web內(nèi)容
stream.pipe(res);
}
else { //文件不存在
//返回404錯誤
res.writeHead(404, {"Content-Type": "text/html"});
res.end("<h1>404 Not Found</h1>");
}
});

二、測試及運(yùn)行
1、完整源碼
以下100行左右的JavaScript就是建立這樣一個簡單web服務(wù)器的全部源碼:
復(fù)制代碼 代碼如下:

//------------------------------------------------
//WebSvr.js
// 一個演示W(wǎng)eb服務(wù)器
//------------------------------------------------
//開始服務(wù)啟動計時器
console.time('[WebSvr][Start]');
//請求模塊
var libHttp = require('http'); //HTTP協(xié)議模塊
var libUrl=require('url'); //URL解析模塊
var libFs = require("fs"); //文件系統(tǒng)模塊
var libPath = require("path"); //路徑解析模塊
//依據(jù)路徑獲取返回內(nèi)容類型字符串,用于http返回頭
var funGetContentType=function(filePath){
var contentType="";
//使用路徑解析模塊獲取文件擴(kuò)展名
var ext=libPath.extname(filePath);
switch(ext){
case ".html":
contentType= "text/html";
break;
case ".js":
contentType="text/javascript";
break;
case ".css":
contentType="text/css";
break;
case ".gif":
contentType="image/gif";
break;
case ".jpg":
contentType="image/jpeg";
break;
case ".png":
contentType="image/png";
break;
case ".ico":
contentType="image/icon";
break;
default:
contentType="application/octet-stream";
}
return contentType; //返回內(nèi)容類型字符串
}
//Web服務(wù)器主函數(shù),解析請求,返回Web內(nèi)容
var funWebSvr = function (req, res){
var reqUrl=req.url; //獲取請求的url
//向控制臺輸出請求的路徑
console.log(reqUrl);
//使用url解析模塊獲取url中的路徑名
var pathName = libUrl.parse(reqUrl).pathname;
if (libPath.extname(pathName)=="") {
//如果路徑?jīng)]有擴(kuò)展名
pathName+="/"; //指定訪問目錄
}
if (pathName.charAt(pathName.length-1)=="/"){
//如果訪問目錄
pathName+="index.html"; //指定為默認(rèn)網(wǎng)頁
}
//使用路徑解析模塊,組裝實際文件路徑
var filePath = libPath.join("./WebRoot",pathName);
//判斷文件是否存在
libPath.exists(filePath,function(exists){
if(exists){//文件存在
//在返回頭中寫入內(nèi)容類型
res.writeHead(200, {"Content-Type": funGetContentType(filePath) });
//創(chuàng)建只讀流用于返回
var stream = libFs.createReadStream(filePath, {flags : "r", encoding : null});
//指定如果流讀取錯誤,返回404錯誤
stream.on("error", function() {
res.writeHead(404);
res.end("<h1>404 Read Error</h1>");
});
//連接文件流和http返回流的管道,用于返回實際Web內(nèi)容
stream.pipe(res);
}
else { //文件不存在
//返回404錯誤
res.writeHead(404, {"Content-Type": "text/html"});
res.end("<h1>404 Not Found</h1>");
}
});
}
//創(chuàng)建一個http服務(wù)器
var webSvr=libHttp.createServer(funWebSvr);
//指定服務(wù)器錯誤事件響應(yīng)
webSvr.on("error", function(error) {
console.log(error); //在控制臺中輸出錯誤信息
});
//開始偵聽8124端口
webSvr.listen(8124,function(){
//向控制臺輸出服務(wù)啟動的信息
console.log('[WebSvr][Start] running at http://127.0.0.1:8124/');
//結(jié)束服務(wù)啟動計時器并輸出
console.timeEnd('[WebSvr][Start]');
});

2、資源目錄

    既然要建立Web服務(wù)器,我們需要創(chuàng)建一個WebRoot目錄來存放實際的網(wǎng)頁和圖片資源,“WebRoot”的目錄名在以上源碼中被用于組裝實際文件路徑。

 

3、運(yùn)行并測試

    在命令行中輸入:

node.exe WebSvr.js

   我們的Web服務(wù)器就運(yùn)行起來了,這時,可以通過瀏覽器對其進(jìn)行訪問,運(yùn)行效果如下:

 

 后記

    利用Node.js我們可以方便建立相對獨(dú)立的Web服務(wù)器,其事件驅(qū)動的特性避免繁瑣的線程保護(hù),其基礎(chǔ)模塊更降低了開發(fā)難度。本章建立的Web服務(wù)器只是一個簡單的樣本,沒有過多的考慮模塊化、安全性等問題,但可以從中掌握Node.js開發(fā)的一些基本的知識。
作者:汪峰 www.otlive.cn

相關(guān)文章

  • 微信小程序--onShareAppMessage分享參數(shù)用處(頁面分享)

    微信小程序--onShareAppMessage分享參數(shù)用處(頁面分享)

    本篇文章主要介紹了微信小程序的頁面分享onShareAppMessage分享參數(shù)用處的相關(guān)資料。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • 如何使用JS console.log()技巧提高工作效率

    如何使用JS console.log()技巧提高工作效率

    這篇文章主要介紹了如何使用JS console.log()技巧提高工作效率,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • JS中箭頭函數(shù)與this的寫法和理解

    JS中箭頭函數(shù)與this的寫法和理解

    這篇文章主要給大家介紹了關(guān)于JS中箭頭函數(shù)與this的寫法和理解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 原生JS 實現(xiàn)的input輸入時表格過濾操作示例

    原生JS 實現(xiàn)的input輸入時表格過濾操作示例

    這篇文章主要介紹了原生JS 實現(xiàn)的input輸入時表格過濾操作,結(jié)合實例形式分析了JavaScript基于頁面元素遍歷、運(yùn)算、判斷實現(xiàn)的表格過濾相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • JavaScript實現(xiàn)表格動態(tài)變色

    JavaScript實現(xiàn)表格動態(tài)變色

    這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)表格動態(tài)變色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 編寫兼容IE和FireFox的腳本

    編寫兼容IE和FireFox的腳本

    編寫兼容IE和FireFox的腳本確定的件很煩人的事,今日又經(jīng)歷了一次。
    2009-05-05
  • js閉包的9個使用場景

    js閉包的9個使用場景

    這篇文章主要介紹了js 閉包的9個使用場景,幫助大家更好的理解和學(xué)習(xí)JavaScript 閉包的使用,感興趣的朋友可以了解下
    2020-12-12
  • 微信小程序template模版的使用方法

    微信小程序template模版的使用方法

    這篇文章主要給大家介紹了關(guān)于微信小程序template模版的使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用微信小程序具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • js將table的每個td的內(nèi)容自動賦值給其title屬性的方法

    js將table的每個td的內(nèi)容自動賦值給其title屬性的方法

    下面小編就為大家?guī)硪黄猨s將table的每個td的內(nèi)容自動賦值給其title屬性的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • javascript中setAttribute兼容性用法分析

    javascript中setAttribute兼容性用法分析

    這篇文章主要介紹了javascript中setAttribute兼容性用法,結(jié)合實例形式分析了javascript使用setAttribute進(jìn)行屬性設(shè)置操作的相關(guān)使用技巧,需要的朋友可以參考下
    2016-12-12

最新評論