NodeJs之初體驗(yàn)06—HTTP

在第一篇了解nodeJs的最后,我們用nodejs創(chuàng)建了一個(gè)簡(jiǎn)單的web服務(wù),其引用的就是http模塊,
所以,我們先起一個(gè)web服務(wù)

let http = require('http');

http.createServer(function(req,res){
    res.writeHead(200,{'Content-Type':'text/plain'});
    res.write("hi,平田君,加嘞個(gè)油~~~");
    res.end();
}).listen(8080);
console.log('server running at http://127.0.0.1:8080/');

然后我們運(yùn)行后發(fā)現(xiàn)事情并沒(méi)有那么簡(jiǎn)單:


出現(xiàn)了亂碼

解決方法:

let http = require('http');
http.createServer(function(req,res){
    res.writeHead(200,{'Content-Type' : 'text/html;charset:utf-8'});
    res.write('<head><meta charset="utf-8"/></head>');
    res.write("hi,平田君,加嘞個(gè)油~~~");
    res.end();
}).listen(8080);
正常了

這是為什么呢?查閱資料后了解到

nodejs不支持完整的Unicode,我們知道nodejs是一個(gè)JavaScript的運(yùn)行環(huán)境,而JavaScript 支持的字符集是雙字節(jié)的UCS2,即用兩個(gè)字節(jié)來(lái)表示一個(gè)Unicode 字符,最大表示的字符數(shù)量是65536。

顯然這是滿(mǎn)足不了很多需求的。所以我們想要用nodejs正常顯示中文,就要做一些事情:
在返回中寫(xiě)入頭部文件,注明 <meta charset="utf-8"/> 直截了當(dāng)告訴瀏覽器要用這種編碼格式解析我的數(shù)據(jù)。
Response.writeHead()方法 就是在返回頁(yè)面中寫(xiě)入頭文件
接著我們開(kāi)始HTTP模塊
如果要在Node.js中使用HTTP服務(wù)器或客戶(hù)端功能,則必須調(diào)用require('http')引入http模塊

http.METHODS

會(huì)返回一個(gè)list 里面包含解析器支持的HTTP方法列表。

http.STATUS_CODES

會(huì)返回全部標(biāo)準(zhǔn)HTTP響應(yīng)狀態(tài)碼的和描述的集合。
例如:http.STATUS_CODES[404] === 'Not Found'



http.createServer([requestListener])

該函數(shù)用來(lái)創(chuàng)建一個(gè)HTTP服務(wù)器,并將 requestListener 作為 request 事件的監(jiān)聽(tīng)函數(shù)。
requestListener 請(qǐng)求處理函數(shù),自動(dòng)添加到 request 事件,函數(shù)傳遞兩個(gè)參數(shù):
req 請(qǐng)求對(duì)象,想知道req有哪些屬性,可以查看 “http.request 屬性整合”。
res 響應(yīng)對(duì)象 ,收到請(qǐng)求后要做出的響應(yīng)。想知道res有哪些屬性,可以查看 “http.response屬性整合”。

http.Server

這是一個(gè)類(lèi),上面的http.createServer(requestListener )方法返回的其實(shí)就是一個(gè)http.server類(lèi)對(duì)象,

http.createServer(function(req,res){
    res.writeHead(200,{'Content-Type' : 'text/html;charset:utf-8'});
    res.write('<head><meta charset="utf-8"/></head>');
    res.write("<h3>hi,平田君,加嘞個(gè)油~~~<h3>");
    res.end('<p>Hello World</p>');
}).listen(8080);

其實(shí)就等價(jià)于

et server = new http.Server();
server.on('request', (req, res)=>{
    res.writeHead(200, {''Content-Type' : 'text/html;charset:utf-8'});
    res.write('<head><meta charset="utf-8"/></head>');
    res.write("<h3>hi,平田君,加嘞個(gè)油~~~<h3>");
    res.end('<p>Hello World</p>');
});
server.listen(8080)

前面說(shuō)到的requestListener自動(dòng)添加到 request 事件 說(shuō)的就是上面的request啦
我們知道request屬于事件的一種,server類(lèi)支持的事件當(dāng)然不止這一種啦

  • request : function (request, response) { }

每當(dāng)有請(qǐng)求的時(shí)候觸發(fā)。注意:每個(gè)連接可以有多個(gè)請(qǐng)求(在keep-alive連接中)

  • connection: function (socket) { }

當(dāng)建立新的TCP流的時(shí)候。socket是一個(gè)net.Socket對(duì)象。通常用戶(hù)不會(huì)訪(fǎng)問(wèn)這個(gè)事件。協(xié)議解析器綁定套接字時(shí)采用的方式使套接字不會(huì)出發(fā)readable事件。也能通過(guò)request.connection訪(fǎng)問(wèn)socket

  • close:function () { }

服務(wù)器關(guān)閉的時(shí)候觸發(fā)

  • checkContinue:function (request, response) { }

當(dāng)http收到100-continue的http請(qǐng)求時(shí)會(huì)觸發(fā)。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件,服務(wù)器將會(huì)自動(dòng)發(fā)送100 Continue的響應(yīng)。
如果客戶(hù)端需要繼續(xù)發(fā)送請(qǐng)求主題,或者生成合適的HTTP響應(yīng)(如,400請(qǐng)求無(wú)效),可以通過(guò)調(diào)用response.writeContinue()來(lái)處理。
注意:觸發(fā)并處理這個(gè)事件的時(shí)候,不會(huì)再觸發(fā)request事件。

  • connect:function (request, socket, head) { }

當(dāng)客戶(hù)端請(qǐng)求http連接時(shí)觸發(fā)。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件,客戶(hù)端請(qǐng)求連接的時(shí)候會(huì)被關(guān)閉。
request是http請(qǐng)求的參數(shù),與request事件參數(shù)相同。
socket是服務(wù)器和客戶(hù)端間的socket。
head是buffer的實(shí)例。網(wǎng)絡(luò)隧道的第一個(gè)包,可能為空。
這個(gè)事件觸發(fā)后,請(qǐng)求的socket不會(huì)有data事件監(jiān)聽(tīng)器,也就是說(shuō)你需要綁定一個(gè)監(jiān)聽(tīng)器到data上,來(lái)處理在發(fā)送到服務(wù)器上的socket數(shù)據(jù)。

  • upgrade:function (request, socket, head) { }

當(dāng)客戶(hù)端請(qǐng)求http upgrage時(shí)候會(huì)觸發(fā)。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件,客戶(hù)端請(qǐng)求一個(gè)連接的時(shí)候會(huì)被關(guān)閉。
這個(gè)事件觸發(fā)后,請(qǐng)求的socket不會(huì)有data事件監(jiān)聽(tīng)器,也就是說(shuō)你需要綁定一個(gè)監(jiān)聽(tīng)器到data上,來(lái)處理在發(fā)送到服務(wù)器上的socket數(shù)據(jù)。

  • clientError:function (exception, socket) { }

如果一個(gè)客戶(hù)端連接觸發(fā)了一個(gè)'error'事件,它就會(huì)轉(zhuǎn)發(fā)到這里.
socket是導(dǎo)致錯(cuò)誤的net.Socket對(duì)象。

Listening事件
以下是server .listen的一些api方法

server.listen(port, [hostname], [backlog], [callback])

  • 監(jiān)聽(tīng)客戶(hù)端連接請(qǐng)求,只有當(dāng)調(diào)用了listen方法以后,服務(wù)器才開(kāi)始工作
  • port : 監(jiān)聽(tīng)的端口
  • hostname : 主機(jī)名(IP/域名)
  • backlog : 連接等待隊(duì)列的最大長(zhǎng)度
  • callback : 調(diào)用listen方法并成功開(kāi)啟監(jiān)聽(tīng)以后,會(huì)觸發(fā)一個(gè)listening事件,callback將作為該事件的執(zhí)行函數(shù)

例如:

server.listen(8080,'127.0.0.1',1,(req,res)=>{
    console.log('22222222');

})

我們監(jiān)聽(tīng)本機(jī)的8080端口,當(dāng)我們一執(zhí)行代碼,在控制窗口就會(huì)打出2222222來(lái)因?yàn)楸O(jiān)聽(tīng)到了8080端口是開(kāi)啟的


server.listen(path[, callback])

啟動(dòng)一個(gè)本地socket服務(wù)器,監(jiān)聽(tīng)指定path的連接。
這是異步函數(shù)。綁定服務(wù)器后,會(huì)觸發(fā)'listening'事件。最后一個(gè)參數(shù)callback將會(huì)作為'listening'事件的監(jiān)聽(tīng)器。
Windows上,本地域通過(guò)命名管道實(shí)現(xiàn)。路徑必須是以\?\pipe\或\.\pipe\入口。任意字符串都可以,不過(guò)之后進(jìn)行相同的管道命名處理,比如解決..序列。管道命名空間是平的。管道不會(huì)一直持久,當(dāng)最后一個(gè)引用關(guān)閉的時(shí)候,管道將會(huì)移除。不要忘記javascript字符字符串轉(zhuǎn)義要求路徑使用雙反斜杠,比如:
net.createServer().listen( path.join('\\?\pipe', process.cwd(), 'myctl'))

server.listen(handle[, callback])

handle 對(duì)象可以設(shè)置成server或socket(任意以下劃線(xiàn)_handle開(kāi)頭的類(lèi)),或者是{fd: <n>}對(duì)象。
這將是服務(wù)器用指定的句柄接收連接,前提是文件描述符或句柄已經(jīng)綁定到端口或域socket。
Windows不支持監(jiān)聽(tīng)文件句柄。
這是異步函數(shù)。當(dāng)服務(wù)器已經(jīng)被綁定,將會(huì)觸發(fā)'listening'事件。最后一個(gè)參數(shù)callback將會(huì)作為'listening'事件的監(jiān)聽(tīng)器。

server.listen(options[, callback])

  • options {Object} - 必須有。支持以下屬性:
  • port {Number} - 可選。
  • host {String} - 可選。
  • backlog {Number} - 可選。
  • path {String} - 可選。
  • exclusive {Boolean} - 可選。
  • callback {Function} - 可選。
    options的屬性:端口port,主機(jī)host,和backlog,以及可選參數(shù)callback函數(shù),他們?cè)谝黄鹫{(diào)用server.listen(port, [host], [backlog], [callback])。還有,參數(shù)path可以用來(lái)指定UNIX socket。
    如果參數(shù)exclusive是false(默認(rèn)值),集群進(jìn)程將會(huì)使用同一個(gè)句柄,允許連接共享。當(dāng)參數(shù)exclusive是true時(shí),句柄不會(huì)共享,如果共享端口會(huì)返回錯(cuò)誤。監(jiān)聽(tīng)獨(dú)家端口例子如下:
server.listen({
  host: 'localhost',
  port: 80,
  exclusive: true
});

server.close([callback])

服務(wù)器停止接收新的連接,保持現(xiàn)有連接。這是異步函數(shù),當(dāng)所有連接結(jié)束的時(shí)候服務(wù)器會(huì)關(guān)閉,并會(huì)觸發(fā)'close'事件。你可以傳一個(gè)回調(diào)函數(shù)來(lái)監(jiān)聽(tīng)'close' 事件。如果存在,將會(huì)調(diào)用回調(diào)函數(shù),錯(cuò)誤(如果有)作為唯一參數(shù)。

server.address()

操作系統(tǒng)返回綁定的地址,協(xié)議族名和服務(wù)器端口。查找哪個(gè)端口已經(jīng)被系統(tǒng)綁定時(shí),非常有用。返回的對(duì)象有3個(gè)屬性,比如:{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

server.getConnections(callback)

異步獲取服務(wù)器當(dāng)前活躍連接的數(shù)量。當(dāng)socket發(fā)送給子進(jìn)程后才有效;
回調(diào)函數(shù)有2個(gè)參數(shù)err和count。

當(dāng)然這些都是我自己在網(wǎng)上看資料的一些心得,可能理解有些偏差或錯(cuò)誤,如果有大神發(fā)現(xiàn),希望可以不吝指正~~如有也是初學(xué)者,希望可以留言探討共同學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容