《node.js權(quán)威指南》(四)node創(chuàng)建http服務(wù)器及客戶端

在Node.js中底挫,提供了http模塊與https模塊汉操,專用于創(chuàng)建HTTP服務(wù)器,HTTP客戶端奔穿,以及HTTPS服務(wù)器和HTTPS客戶端,同事實現(xiàn)這些服務(wù)器端與客戶端之中所需要進(jìn)行的處理敏晤。

http服務(wù)器

引用http模塊,調(diào)用http模塊中的createServer方法,在createServer的回調(diào)函數(shù)中處理用戶請求
創(chuàng)建http服務(wù)器

var http = require('http');
// 調(diào)用http模塊中的createServer方法
// 在createServer的回調(diào)函數(shù)中處理用戶請求
var server = http.createServer(function(req,res){
    // 第一個參數(shù)是客戶端的請求對象贱田,
    // 第二個參叔代表服務(wù)器相應(yīng)對象
    // 接受客戶端請求時的其他他處理
});
server.listen(3000,"127.0.0.1");

request事件

// 可以監(jiān)聽http.createServer方法創(chuàng)建的服務(wù)器對象的request時間
// request表示接受到客戶端請求時所需要處理
server.on('request',function(request,response){
    // 第一個參數(shù)是客戶端的請求對象,
    // 第二個參叔代表服務(wù)器相應(yīng)對象
    console.log('')
})

listening事件

// 當(dāng)對http服務(wù)器指定了需要監(jiān)聽的地址和端口后嘴脾,服務(wù)器將立即開始監(jiān)
// 聽來自改地址及端口的客戶端鏈接男摧,這時觸發(fā)該服務(wù)器的listening事件
// 可以通過監(jiān)聽http服務(wù)器對象的listening事件,并且指定該時間觸發(fā)時
// 調(diào)用的回調(diào)函數(shù)的方法來指定http服務(wù)器開始監(jiān)聽時所需執(zhí)行的處理
server.on('listening',function(){
    // 回調(diào)函數(shù)為可選參數(shù)
    console.log('服務(wù)器端開始監(jiān)聽')
});

close事件

// 這段代碼中由于沒有關(guān)閉http服務(wù)器译打,因此該服務(wù)器將一直監(jiān)聽來自于
// 指定地址及端口的客戶端鏈接耗拓,應(yīng)用程序?qū)⒉粫顺觯?dāng)http服務(wù)器被關(guān)閉時
// 如果服務(wù)器尚未與任何客戶端建立鏈接奏司,應(yīng)用程序?qū)⒄M顺觥?// 當(dāng)http服務(wù)器被關(guān)閉后乔询,將不再接受來自listen方法中指定的地址及端口號
// 的客戶端鏈接。
// 可以使用客戶端的close方法關(guān)閉該服務(wù)器
server.on('close',function(){
    // 回調(diào)函數(shù)為可選參數(shù)
    console.log('服務(wù)器已關(guān)閉')
})

error事件

// 在對HTTP服務(wù)器指定需要監(jiān)聽的地址及端口時结澄,如果該地址及端口已被占用
// 將產(chǎn)生錯誤哥谷,觸發(fā)服務(wù)器的error事件,可以通過對error事件設(shè)置回調(diào)函數(shù)
// 的方法來指定該錯誤產(chǎn)生時所需要執(zhí)行的處理
server.on('error',function(e){
    // 回調(diào)函數(shù)為可選參數(shù)
    console.log(e)
    console.log('服務(wù)器鏈接失敗')
})

connection事件

// 當(dāng)客戶端與服務(wù)器端建立鏈接時麻献,觸發(fā)http服務(wù)器對象 connection事件
// 可以監(jiān)聽該事件并在該事件觸發(fā)時調(diào)用的回調(diào)函數(shù)中指定當(dāng)連接建立時所需要
// 執(zhí)行的處理
server.on('connection',function(socket){
    console.log('客戶端連接已建立')
})
// 客戶端會輸出兩次"客戶端連接已建立",這是因為在瀏覽器訪問http服務(wù)器時,
// 瀏覽器會發(fā)出兩次客戶端請求猜扮,一次是用戶發(fā)出的請求勉吻,另一次是瀏覽器為頁面在收藏夾
// 中顯示圖標(biāo)(favicon.ico)而自動發(fā)出的請求

timeOut事件

// 在node中,將http服務(wù)器的默認(rèn)超時時間設(shè)置為2分鐘
// 當(dāng)服務(wù)器超時時旅赢,觸發(fā)該服務(wù)器對象的timeout事件
server.on('timeout',function(socket){
    // socket為服務(wù)器端用于監(jiān)聽客戶端請求的socket對象
})

setTimeout服務(wù)器超時事件

// 可以使用http服務(wù)器的setTimeout方法來設(shè)置服務(wù)器的超時時間
// 當(dāng)該超時時間超過之后齿桃,客戶端不可繼續(xù)利用本次與HTTP服務(wù)器建立鏈接
// 下次向該服務(wù)器發(fā)出請求時必須重新建立連接
server.setTimeout(60*1000,function(socket){
    console.log('服務(wù)器超時')
})
console.log(server.timeout) //可以查看服務(wù)器的超時時間

獲取客戶端信息

獲取客戶端信息

如下

var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
    if(req.url !== '/favicon.ico'){
        var out = fs.createWriteStream('./request.log');
        out.write('客戶端請求方法'+req.method+'\r\n');
        out.write('客戶端請求url'+req.url+'\r\n');
        out.write('客戶端請求頭對象'+JSON.stringify(req.headers)+'\r\n');
        out.end('客戶端請求所用http版本'+req.httpVersion)
    }
    res.end();
})
server.listen(3000,"127.0.0.1");

運(yùn)行代碼惑惶,在應(yīng)用程序的根目錄下將創(chuàng)建一個request.log文件,打開該文件短纵,顯示如下


案例效果

轉(zhuǎn)換URL字符串與查詢字符串

在node中带污,提供了一個url模塊與Query String模塊,分別用來轉(zhuǎn)換完整URL字符串與URL中的查詢字符串香到。

querystring.parse(str, [sep], [eq], [opaction])

我們用的時候鱼冀,基本上后三個參數(shù)用默認(rèn)的就好
這樣當(dāng)我們參數(shù)為username=luckFine & age=14 & sex = boy
那么當(dāng)調(diào)用parse方法時querystring.parse(username=luckFine & age=14 & sex = boy)
結(jié)果就是

{
  username : luckFine,
  age : 14,
  sex : boy
}

當(dāng)客戶端提交表單數(shù)據(jù)時,且表單中存在復(fù)選框時悠就,提交的查詢字符串存在類似username=luckFine & username=xiaoFan 這種形式的字符串千绪,在使用parse方法后,這種形式的字符串將轉(zhuǎn)化為對象中的一個數(shù)組梗脾。

{
  username : [luckFine, xiaoFan],
  age : 14,
  sex : boy
}

反過來荸型,querystring.stringify(obj) 可以將對象轉(zhuǎn)化為一個查詢字符串,例如
querystring.stringify({username : luckFine,age : 14,
sex : boy})
那么運(yùn)行結(jié)果為 username=luckFine & age=14 & sex = boy

那么基于這個,在node中的url模塊炸茧,專門于對完整的URL字符串進(jìn)行轉(zhuǎn)換瑞妇。
在url模塊中可以使用parse方法將url字符串轉(zhuǎn)換為一個對象,根據(jù)URL字符串中的不同內(nèi)容梭冠,該對象中可能具有的屬性及含義如下

案例如下

運(yùn)行結(jié)果

相反踪宠,可以使用url模塊中的format方法將URL字符串經(jīng)過轉(zhuǎn)換后的對象還原為一個URL字符串。
url.format(urlObj)

屏幕快照 2018-01-02 下午10.20.37.png

我們看一下在http服務(wù)器中解析url字符串的代碼示例

var http = require('http');
var url = require('url');
var server = http.createServer(function(req,res){
    if(req.url !== '/favicon.ico'){
        res.write('<html><head><meta charset="utf-8"></head>')
        var url_parts = url.parse(req.url);
        switch (url_parts.pathname) {
            case '/':
            case '/index.html':
                res.write('<body><h1>您正訪問的是首頁</h1></body></html>')
                break;
            default:
                res.write('<body><h1>您正訪問的是'+url_parts.pathname+'</h1></body></html>')
                break;
        }
    }
    res.end();
})
server.listen(3000,"127.0.0.1");

發(fā)送服務(wù)器端響應(yīng)流

在發(fā)送請求的時候妈嘹,我們需要發(fā)送響應(yīng)頭
response.writeHead(statusCode,[reasonPhrase],[headers])

statusCode為一個三位的http狀態(tài)碼 例如200
reasonPhrase參數(shù)值為一個字符串柳琢,用于指定對于該狀態(tài)碼的描述信息
headers為一個對象,用于指定服務(wù)器創(chuàng)建的響應(yīng)頭對象

響應(yīng)頭對象

如下

var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
    if(req.url !== '/favicon.ico'){
        res.writeHead(200,{'Content-Type':'text/plain;charset=UTF-8',
            'Access-Control-Allow-Origin':'http://localhost'});
        res.write("你好")
    }
    res.end();
})
server.listen(3000,"127.0.0.1");

也可以用http.ServerResponse對象的setHeader方法來設(shè)置響應(yīng)頭

var http = require('http');
var fs = require('fs');
var server = http.createServer(function(req,res){
    if(req.url !== '/favicon.ico'){
        res.setHeader('Content-Type','text/plain;charset=UTF-8');
        res.setHeader('Access-Control-Allow-Origin','http://localhost');
        res.write("你好ma")
    }
    res.end();
})
server.listen(3000,"127.0.0.1");

用setHeader設(shè)置響應(yīng)頭信息之后润脸,可以用getHeader獲取響應(yīng)頭的某個字段
response.getHeader(name)
或者用removeHeader(name) 移除某個響應(yīng)頭,但是用removeHeader(name)移除某個響應(yīng)頭的時候柬脸,必須在ServerResponse對象的write方法發(fā)送數(shù)據(jù)之前被調(diào)用。

通過示例來看響應(yīng)頭的發(fā)送時機(jī)

var http = require('http');
var server = http.createServer(function(req,res){
    if(req.url !== '/favicon.ico'){
        console.log(res.headersSent)
        if(res.headersSent){
            console.log('響應(yīng)頭已發(fā)送')
        }else{
            console.log('響應(yīng)頭未發(fā)送')
        }
        res.writeHeader(200,{'Content-Type':'text/html'});
        if(res.headersSent){
            console.log('響應(yīng)頭已發(fā)送0')
        }else{
            console.log('響應(yīng)頭未發(fā)送0')
        }
        res.write("你好")
    }
    res.end();
})
server.listen(3000,"127.0.0.1");
查看響應(yīng)頭

在使用setHeader方法時毙驯,當(dāng)http.ServerResponse對象的write方法被第一次調(diào)用時及發(fā)送響應(yīng)頭倒堕。

HTTP客戶端

在node中,可以用request任何網(wǎng)站發(fā)送請求并讀取該網(wǎng)站的相應(yīng)數(shù)據(jù)


向其他網(wǎng)站請求數(shù)據(jù)
假設(shè)我向百度請求數(shù)據(jù)
示例如下

var http = require('http');
// 設(shè)置請求信息
var options = {
    hostname:'www.baidu.com',
    post:80,
    path:'/',
    method:'GET'
};
var req = http.request(options,function(res){
    console.log('狀態(tài)碼'+res.statusCode);
    console.log('響應(yīng)頭'+JSON.stringify(res.headers));
    // res.setEncoding() 用來指定用如何編碼該字符串
    res.setEncoding('utf-8');
    // 當(dāng)請求到數(shù)據(jù)的時候爆价,對數(shù)據(jù)進(jìn)行操作
    res.on('data',function(chunk){
        console.log('相應(yīng)內(nèi)容'+chunk)
    })
    // 當(dāng)請求超時調(diào)用req.setTimeout函數(shù)
    req.setTimeout(1000,function(){
        // req.about()終止本次請求
        req.about();
    })
    // 當(dāng)請求失敗時垦巴,查看失敗原因
    req.on('error',function(err){
        console.log('請求數(shù)據(jù)發(fā)生錯誤,錯誤代碼'+err.code);
    })
})

req.end();

由于請求結(jié)果過多铭段,那么我截取其中一小部分


請求百度

同志們骤宣,點贊不花錢~給程序媛一個小谷粒噻

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市序愚,隨后出現(xiàn)的幾起案子憔披,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芬膝,死亡現(xiàn)場離奇詭異望门,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)锰霜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門筹误,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人癣缅,你說我怎么就攤上這事厨剪。” “怎么了所灸?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵丽惶,是天一觀的道長。 經(jīng)常有香客問我爬立,道長钾唬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任侠驯,我火速辦了婚禮抡秆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吟策。我一直安慰自己儒士,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布檩坚。 她就那樣靜靜地躺著着撩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匾委。 梳的紋絲不亂的頭發(fā)上拖叙,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機(jī)與錄音赂乐,去河邊找鬼薯鳍。 笑死,一個胖子當(dāng)著我的面吹牛挨措,可吹牛的內(nèi)容都是我干的挖滤。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼浅役,長吁一口氣:“原來是場噩夢啊……” “哼斩松!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起担租,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤砸民,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后奋救,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岭参,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年尝艘,在試婚紗的時候發(fā)現(xiàn)自己被綠了演侯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡背亥,死狀恐怖秒际,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狡汉,我是刑警寧澤娄徊,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站盾戴,受9級特大地震影響寄锐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尖啡,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一橄仆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衅斩,春花似錦盆顾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奠涌,卻和暖如春宪巨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铣猩。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工揖铜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人达皿。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓天吓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峦椰。 傳聞我的和親對象是個殘疾皇子龄寞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)汤功,斷路器物邑,智...
    卡卡羅2017閱讀 134,713評論 18 139
  • 個人入門學(xué)習(xí)用筆記、不過多作為參考依據(jù)。如有錯誤歡迎斧正 目錄 簡書好像不支持錨點色解、復(fù)制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,479評論 1 37
  • xdh精英班20160909課后作業(yè): Node.js HTTP 介紹 本文根據(jù)xdh精英班20160909課后作...
    birdflying閱讀 878評論 0 4
  • 前言 在swift中,不同類型之間是不能進(jìn)行運(yùn)算的,需要強(qiáng)制類型轉(zhuǎn)換, 但是特別需要注意的一點: 如果說是字面量之...
    Alexander閱讀 222評論 0 1
  • 第一次看見這本書茂嗓,就被名字所吸引。后來因為電影的契機(jī)科阎,再一次重溫了一遍述吸,似乎每看完一次都有著不同的感慨。它不同于其...
    simple115閱讀 268評論 0 1