HTTP入門(三):使用Nodo.js腳本實(shí)現(xiàn)簡易服務(wù)器
- 本文通過簡單的Node.js腳本模擬服務(wù)器請(qǐng)求與響應(yīng)原理鳞贷。
- 本文主要目的是對(duì)學(xué)習(xí)內(nèi)容進(jìn)行總結(jié)以及方便日后查閱掸屡。
- 本文所引用的圖片和文字版權(quán)歸原作者所有喻鳄,侵權(quán)刪。
- 如有錯(cuò)誤請(qǐng)?jiān)谙路皆u(píng)論區(qū)指出开仰,歡迎積極討論蕊肥。
前言
- 硬件服務(wù)器:我們的電腦就是一個(gè)服務(wù)器。和普通的服務(wù)器的區(qū)別是:真正的服務(wù)器CPU可能有128G核扳埂,32业簿、64、128G內(nèi)存阳懂。沒有GUI梅尤,沒有顯示器,用ssh遠(yuǎn)程登錄岩调,本質(zhì)還是電腦
- 軟件服務(wù)器:服務(wù)器上的軟件巷燥。
服務(wù)器你已經(jīng)有了,你使用的電腦就是服務(wù)器号枕。但是你還沒有提供 HTTP 服務(wù)的「程序」缰揪。
用腳本就可以提供 HTTP 服務(wù),不管是 Bash 腳本還是 Node.js 腳本都可以葱淳。這篇文章先用 Node.js 腳本試試水钝腺。
接收請(qǐng)求
我們的腳本只需要一個(gè)文件就可以搞定:
-
新建一個(gè)安全的目錄
cd ~/Desktop mkdir node-demo cd node-demo
touch server.js
-
編輯
server.js
,內(nèi)容已上傳到GitHub抛姑,所以用命令curl https://raw.githubusercontent.com/mtt3366/nodeserver/master/NodeServer.js > ./server.js
拷貝代碼到
server.js
示例
-
cat server.js
查看內(nèi)容是否已經(jīng)拷貝。
查看 -
node server.js 8888
監(jiān)聽8888本地端口艳狐,這里端口參數(shù)不建議寫0-1023定硝,因?yàn)樾∮?024已經(jīng)被規(guī)定使用,需要管理員權(quán)限才可以訪問毫目。 - 成功之后蔬啡,這個(gè) server 會(huì)保持運(yùn)行,無法退出蒜茴。
- 如果你想「中斷」這個(gè) server星爪,按 <kbd>Ctrl</kbd> + <kbd>C</kbd> 即可(C 就是 Cancel 的意思)浆西,中斷后你才能輸入其他命令粉私。
- 把這個(gè) server 放在那里別動(dòng),新開一個(gè) Bash 窗口近零,完成下面的測試
好了服務(wù)器完成诺核。只不過
- 這個(gè)服務(wù)器目前只有一個(gè)功能,那就是打印出路徑和查詢字符串
- 還缺少一個(gè)重要的功能久信,那就是發(fā)出 HTTP 響應(yīng)窖杀,目前我們先不發(fā)出響應(yīng)
接下來要發(fā)起一個(gè)請(qǐng)求到這個(gè)服務(wù)器。這聽起來有點(diǎn)怪異裙士,「我向自己發(fā)起請(qǐng)求」入客,目前是的,因?yàn)槲覀兊碾娔X既是客戶端腿椎,又是服務(wù)器桌硫,還是會(huì)經(jīng)歷HTTP協(xié)議,還是會(huì)走一遍TCP/IP協(xié)議啃炸,所以用本機(jī)來學(xué)習(xí)服務(wù)器原理可行铆隘。接下來
-
在新的 Bash 窗口運(yùn)行
curl http://localhost:8888/xxx
或者curl http://127.0.0.1:8888/xxx
。
你會(huì)馬上發(fā)現(xiàn) server 打印出了路徑:
MTT說:得到 HTTP 路徑
/xxx
MTT說:查詢字符串為MTT說:不含查詢字符串的路徑為
/xxx
這說明:
- 我們的 server 收到了我們用 curl 發(fā)出的請(qǐng)求
- 由于 server 遲遲沒有發(fā)出響應(yīng)南用,所以 curl 就一直等在那里膀钠,無法退出(用 <kbd>Ctrl</kbd> + <kbd>C</kbd> 中斷這個(gè)傻 curl)
- 運(yùn)行
curl "http://127.0.0.1:8888/xxx?name=ff"
打印結(jié)果:
MTT說:得到 HTTP 路徑
/xxx?name=ff
MTT說:查詢字符串為
?name=ff
MTT說:不含查詢字符串的路徑為
/xxx
這個(gè)服務(wù)器就一個(gè)功能,把路徑和查詢參數(shù)打印出來裹虫,不發(fā)出響應(yīng)
發(fā)出響應(yīng)
接下來我們讓我們 server 發(fā)出響應(yīng)肿嘲,不在讓客戶端端一直等我們
- 編輯
server.js
- 在中間我標(biāo)注的區(qū)域添加兩行代碼
response.write('Hi')
-
response.end()
如果沒有這句話,客戶端還會(huì)一直等 - 中斷之前的 server筑公,重新運(yùn)行
node server 8888
-
curl http://127.0.0.1:8888/xxx
睦刃,結(jié)果如下: -
Hi%
這個(gè) % 不是我們的內(nèi)容,% 表示結(jié)尾十酣。如果你看 % 不爽涩拙,就把 'Hi' 換成'Hi\n'
际长。 - 響應(yīng)添加成功
- 使用
curl -s -v -- "http://localhost:8888/xxx"
可以查看完整的請(qǐng)求和響應(yīng)示例
根據(jù)請(qǐng)求返回不同的響應(yīng)
響應(yīng) /
與404
將中間的代碼改為
if(path == "/" ){
response.write('Hi')
response.end()
} else{
response.statusCode = 404
response.end()
}
代碼示例
不同的請(qǐng)求返回內(nèi)容的截圖
響應(yīng)404
響應(yīng)/
響應(yīng) /index.html
代碼修改
響應(yīng)示例
強(qiáng)調(diào):后綴是廢話。文件內(nèi)容是有 HTTP 頭中的
Content-Type
保證的
響應(yīng)真正的網(wǎng)頁
- 完整代碼:
var http = require('http')
var fs = require('fs')
var url = require('url')
var port = process.argv[2]
if(!port){
console.log('請(qǐng)指定端口號(hào)好不啦兴泥?\nnode server.js 8888 這樣不會(huì)嗎工育?')
process.exit(1)
}
var server = http.createServer(function(request, response){
var parsedUrl = url.parse(request.url, true)
var path = request.url
var query = ''
if(path.indexOf('?') >= 0){ query = path.substring(path.indexOf('?')) }
var pathNoQuery = parsedUrl.pathname
var queryObject = parsedUrl.query
var method = request.method
/******** 從這里開始看,上面不要看 ************/
console.log('HTTP 路徑為\n' + path)
if(path == '/style.js'){
response.setHeader('Content-Type', 'text/css; charset=utf-8')
response.write('body{background-color: #ddd;}h1{color: red;}')
response.end()
}else if(path == '/script.html'){
response.setHeader('Content-Type', 'text/javascript; charset=utf-8')
response.write('alert("這是JS執(zhí)行的")')
response.end()
}else if(path == '/index.css'){
response.setHeader('Content-Type', 'text/html; charset=utf-8')
response.write('<!DOCTYPE>\n<html>' +
'<head><link rel="stylesheet" href="/style.js">' +
'</head><body>' +
'<h1>你好</h1>' +
'<script src="/script.html"></script>' +
'</body></html>')
response.end()
}else{
response.statusCode = 404
response.end()
}
/******** 代碼結(jié)束搓彻,下面不要看 ************/
})
server.listen(port)
console.log('監(jiān)聽 ' + port + ' 成功\n請(qǐng)用在空中轉(zhuǎn)體720度然后用電飯煲打開 http://localhost:' + port)
-
接下來
curl -s -v – "http://localhost:8888"
image 因?yàn)轫憫?yīng)中
<link rel="stylesheet" href="/style.js">
和<script src="/script.html"></script>
服務(wù)器會(huì)接著繼續(xù)發(fā)出/script
和/style
響應(yīng)如绸。包括圖片路徑,也會(huì)發(fā)出響應(yīng)旭贬。
-
模擬一下
/script
和/style
響應(yīng)怔接。
image -
為了證實(shí)我們的想法,打開network查看請(qǐng)求與響應(yīng)稀轨。發(fā)現(xiàn)確實(shí)有三個(gè)響應(yīng)扼脐。
image