HTTP入門(三):使用Nodo.js腳本實(shí)現(xiàn)簡易服務(wù)器

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ù)器完成诺核。只不過
  1. 這個(gè)服務(wù)器目前只有一個(gè)功能,那就是打印出路徑查詢字符串
  2. 還缺少一個(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

這說明:

  1. 我們的 server 收到了我們用 curl 發(fā)出的請(qǐng)求
  2. 由于 server 遲遲沒有發(fā)出響應(yīng)南用,所以 curl 就一直等在那里膀钠,無法退出(用 <kbd>Ctrl</kbd> + <kbd>C</kbd> 中斷這個(gè)傻 curl)
  3. 運(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)肿嘲,不在讓客戶端端一直等我們

  1. 編輯 server.js
  2. 在中間我標(biāo)注的區(qū)域添加兩行代碼
  3. response.write('Hi')
  4. response.end() 如果沒有這句話,客戶端還會(huì)一直等
  5. 中斷之前的 server筑公,重新運(yùn)行 node server 8888
  6. curl http://127.0.0.1:8888/xxx睦刃,結(jié)果如下:
  7. Hi%
    這個(gè) % 不是我們的內(nèi)容,% 表示結(jié)尾十酣。如果你看 % 不爽涩拙,就把 'Hi' 換成 'Hi\n'际长。
  8. 響應(yīng)添加成功
  9. 使用 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

1

響應(yīng)/

image

響應(yīng) /index.html

代碼修改


image

響應(yīng)示例


image

強(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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奋刽,隨后出現(xiàn)的幾起案子瓦侮,更是在濱河造成了極大的恐慌,老刑警劉巖佣谐,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肚吏,死亡現(xiàn)場離奇詭異,居然都是意外死亡狭魂,警方通過查閱死者的電腦和手機(jī)罚攀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雌澄,“玉大人斋泄,你說我怎么就攤上這事≈阑铮” “怎么了是己?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長任柜。 經(jīng)常有香客問我卒废,道長,這世上最難降的妖魔是什么宙地? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任摔认,我火速辦了婚禮,結(jié)果婚禮上宅粥,老公的妹妹穿的比我還像新娘参袱。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布抹蚀。 她就那樣靜靜地躺著剿牺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪环壤。 梳的紋絲不亂的頭發(fā)上晒来,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音郑现,去河邊找鬼湃崩。 笑死,一個(gè)胖子當(dāng)著我的面吹牛接箫,可吹牛的內(nèi)容都是我干的攒读。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼辛友,長吁一口氣:“原來是場噩夢啊……” “哼薄扁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞎领,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤泌辫,失蹤者是張志新(化名)和其女友劉穎随夸,沒想到半個(gè)月后九默,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宾毒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年驼修,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈铛。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乙各,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幢竹,到底是詐尸還是另有隱情耳峦,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布焕毫,位于F島的核電站蹲坷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏邑飒。R本人自食惡果不足惜循签,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疙咸。 院中可真熱鬧县匠,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兰粉,卻和暖如春扮惦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亲桦。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國打工崖蜜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人客峭。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓豫领,卻偏偏與公主長得像,于是被迫代替她去往敵國和親舔琅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子等恐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)备蚓,斷路器课蔬,智...
    卡卡羅2017閱讀 134,722評(píng)論 18 139
  • Node.js是目前非常火熱的技術(shù)郊尝,但是它的誕生經(jīng)歷卻很奇特二跋。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,076評(píng)論 2 58
  • xdh精英班20160909課后作業(yè): Node.js HTTP 介紹 本文根據(jù)xdh精英班20160909課后作...
    birdflying閱讀 878評(píng)論 0 4
  • 01 喬布斯沒有爭辯說開公司他們一定能賺錢流昏,而是說這一定會(huì)是一次有趣的經(jīng)歷扎即。即使賠了錢,他們也能擁有一家公司况凉,這比...
    小碗月牙閱讀 240評(píng)論 0 0
  • 心甘情愿的做那些你認(rèn)為好的事谚鄙,比如健身,比如寫作刁绒,不要把他們當(dāng)做負(fù)擔(dān)闷营,因?yàn)槟愕某踔允亲屪约嚎鞓贰?/div>
    阿凱同學(xué)閱讀 126評(píng)論 0 0